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