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}