schemars/
lib.rs

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