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}