schemars/lib.rs
1#![forbid(unsafe_code)]
2#![deny(
3 missing_docs,
4 unused_imports,
5 unused_qualifications,
6 clippy::cargo,
7 clippy::pedantic,
8 clippy::exhaustive_structs,
9 clippy::exhaustive_enums
10)]
11#![allow(clippy::wildcard_imports, clippy::missing_errors_doc)]
12#![doc = include_str!("../README.md")]
13#![no_std]
14
15extern crate alloc;
16#[cfg(feature = "std")]
17extern crate std;
18
19mod encoding;
20mod json_schema_impls;
21mod schema;
22mod ser;
23#[macro_use]
24mod macros;
25
26/// This module is only public for use by `schemars_derive`. It should not need to be used by code
27/// outside of `schemars`, and should not be considered part of the public API.
28#[doc(hidden)]
29#[allow(clippy::exhaustive_structs)]
30pub mod _private;
31pub mod consts;
32pub mod generate;
33pub mod transform;
34
35#[cfg(feature = "schemars_derive")]
36extern crate schemars_derive;
37use alloc::borrow::Cow;
38
39#[cfg(feature = "schemars_derive")]
40pub use schemars_derive::*;
41
42#[doc(inline)]
43pub use generate::SchemaGenerator;
44pub use schema::Schema;
45
46mod _alloc_prelude {
47 pub use alloc::borrow::ToOwned;
48 pub use alloc::boxed::Box;
49 pub use alloc::format;
50 pub use alloc::string::{String, ToString};
51 pub use alloc::vec;
52 pub use alloc::vec::Vec;
53}
54
55/// A type which can be described as a JSON Schema document.
56///
57/// This is implemented for many Rust primitive and standard library types.
58///
59/// This can also be automatically derived on most custom types with `#[derive(JsonSchema)]` by
60/// enabling the `derive` feature flag (which is enabled by default).
61/// For more info on deriving `JsonSchema`, see [the derive macro documentation](derive@JsonSchema).
62///
63/// # Examples
64/// Deriving an implementation:
65/// ```
66/// use schemars::{schema_for, JsonSchema};
67///
68/// #[derive(JsonSchema)]
69/// struct MyStruct {
70/// foo: i32,
71/// }
72///
73/// let my_schema = schema_for!(MyStruct);
74/// ```
75///
76/// When manually implementing `JsonSchema`, as well as determining an appropriate schema,
77/// you will need to determine an appropriate name and ID for the type.
78/// For non-generic types, the type name/path are suitable for this:
79/// ```
80/// use schemars::{SchemaGenerator, Schema, JsonSchema, json_schema};
81/// use std::borrow::Cow;
82///
83/// struct NonGenericType;
84///
85/// impl JsonSchema for NonGenericType {
86/// fn schema_name() -> Cow<'static, str> {
87/// // Exclude the module path to make the name in generated schemas clearer.
88/// "NonGenericType".into()
89/// }
90///
91/// fn schema_id() -> Cow<'static, str> {
92/// // Include the module, in case a type with the same name is in another module/crate
93/// concat!(module_path!(), "::NonGenericType").into()
94/// }
95///
96/// fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
97/// json_schema!({
98/// "foo": "bar"
99/// })
100/// }
101/// }
102///
103/// assert_eq!(NonGenericType::schema_id(), <&mut NonGenericType>::schema_id());
104/// ```
105///
106/// But generic type parameters which may affect the generated schema should typically be included
107/// in the name/ID:
108/// ```
109/// use schemars::{SchemaGenerator, Schema, JsonSchema, json_schema};
110/// use std::{borrow::Cow, marker::PhantomData};
111///
112/// struct GenericType<T>(PhantomData<T>);
113///
114/// impl<T: JsonSchema> JsonSchema for GenericType<T> {
115/// fn schema_name() -> Cow<'static, str> {
116/// format!("GenericType_{}", T::schema_name()).into()
117/// }
118///
119/// fn schema_id() -> Cow<'static, str> {
120/// format!(
121/// "{}::GenericType<{}>",
122/// module_path!(),
123/// T::schema_id()
124/// ).into()
125/// }
126///
127/// fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
128/// json_schema!({
129/// "foo": "bar"
130/// })
131/// }
132/// }
133///
134/// assert_eq!(<GenericType<i32>>::schema_id(), <&mut GenericType<&i32>>::schema_id());
135/// ```
136pub trait JsonSchema {
137 /// Whether JSON Schemas generated for this type should be included directly in parent schemas,
138 /// rather than being re-used where possible using the `$ref` keyword.
139 ///
140 /// For trivial types (such as primitives), this should return `true`. For more complex types,
141 /// it should return `false`. For recursive types, this **must** return `false` to prevent
142 /// infinite cycles when generating schemas.
143 ///
144 /// By default, this returns `false`.
145 #[must_use]
146 fn inline_schema() -> bool {
147 false
148 }
149
150 /// The name of the generated JSON Schema.
151 ///
152 /// This is used as the title for root schemas, and the key within the root's `definitions`
153 /// property for subschemas.
154 #[must_use]
155 fn schema_name() -> Cow<'static, str>;
156
157 /// Returns a string that uniquely identifies the schema produced by this type.
158 ///
159 /// This does not have to be a human-readable string, and the value will not itself be included
160 /// in generated schemas. If two types produce different schemas, then they **must** have
161 /// different `schema_id()`s, but two types that produce identical schemas should *ideally*
162 /// have the same `schema_id()`.
163 ///
164 /// The default implementation returns the same value as
165 /// [`schema_name()`](JsonSchema::schema_name).
166 #[must_use]
167 fn schema_id() -> Cow<'static, str> {
168 Self::schema_name()
169 }
170
171 /// Generates a JSON Schema for this type.
172 ///
173 /// If the returned schema depends on any [non-inlined](JsonSchema::inline_schema)
174 /// schemas, then this method will add them to the [`SchemaGenerator`]'s schema definitions.
175 ///
176 /// This should not return a `$ref` schema.
177 fn json_schema(generator: &mut SchemaGenerator) -> Schema;
178
179 // TODO document and bring into public API?
180 #[doc(hidden)]
181 fn _schemars_private_non_optional_json_schema(generator: &mut SchemaGenerator) -> Schema {
182 Self::json_schema(generator)
183 }
184
185 // TODO document and bring into public API?
186 #[doc(hidden)]
187 #[must_use]
188 fn _schemars_private_is_option() -> bool {
189 false
190 }
191}