Skip to main content

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}