schemars/
_private.rs
1use crate::r#gen::SchemaGenerator;
2use crate::schema::{InstanceType, ObjectValidation, Schema, SchemaObject};
3use crate::{JsonSchema, Map, Set};
4use serde::Serialize;
5use serde_json::Value;
6
7pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
9 generator: &mut SchemaGenerator,
10 required: bool,
11) -> Schema {
12 let mut schema = T::_schemars_private_non_optional_json_schema(generator);
13
14 if T::_schemars_private_is_option() && !required {
15 if let Schema::Object(SchemaObject {
16 object: Some(ref mut object_validation),
17 ..
18 }) = schema
19 {
20 object_validation.required.clear();
21 }
22 }
23
24 schema
25}
26
27#[doc(hidden)]
32#[macro_export]
33macro_rules! _schemars_maybe_to_value {
34 ($expression:expr) => {{
35 #[allow(unused_imports)]
36 use $crate::_private::{MaybeSerializeWrapper, NoSerialize as _};
37
38 MaybeSerializeWrapper($expression).maybe_to_value()
39 }};
40}
41
42pub struct MaybeSerializeWrapper<T>(pub T);
43
44pub trait NoSerialize: Sized {
45 fn maybe_to_value(self) -> Option<Value> {
46 None
47 }
48}
49
50impl<T> NoSerialize for T {}
51
52impl<T: Serialize> MaybeSerializeWrapper<T> {
53 pub fn maybe_to_value(self) -> Option<Value> {
54 serde_json::value::to_value(self.0).ok()
55 }
56}
57
58pub fn new_unit_enum(variant: &str) -> Schema {
60 Schema::Object(SchemaObject {
61 instance_type: Some(InstanceType::String.into()),
62 enum_values: Some(vec![variant.into()]),
63 ..SchemaObject::default()
64 })
65}
66
67pub fn new_externally_tagged_enum(variant: &str, sub_schema: Schema) -> Schema {
69 Schema::Object(SchemaObject {
70 instance_type: Some(InstanceType::Object.into()),
71 object: Some(Box::new(ObjectValidation {
72 properties: {
73 let mut props = Map::new();
74 props.insert(variant.to_owned(), sub_schema);
75 props
76 },
77 required: {
78 let mut required = Set::new();
79 required.insert(variant.to_owned());
80 required
81 },
82 additional_properties: Some(Box::new(false.into())),
89 ..Default::default()
90 })),
91 ..SchemaObject::default()
92 })
93}
94
95pub fn new_internally_tagged_enum(
97 tag_name: &str,
98 variant: &str,
99 deny_unknown_fields: bool,
100) -> Schema {
101 let tag_schema = Schema::Object(SchemaObject {
102 instance_type: Some(InstanceType::String.into()),
103 enum_values: Some(vec![variant.into()]),
104 ..Default::default()
105 });
106 Schema::Object(SchemaObject {
107 instance_type: Some(InstanceType::Object.into()),
108 object: Some(Box::new(ObjectValidation {
109 properties: {
110 let mut props = Map::new();
111 props.insert(tag_name.to_owned(), tag_schema);
112 props
113 },
114 required: {
115 let mut required = Set::new();
116 required.insert(tag_name.to_owned());
117 required
118 },
119 additional_properties: deny_unknown_fields.then(|| Box::new(false.into())),
120 ..Default::default()
121 })),
122 ..SchemaObject::default()
123 })
124}
125
126pub fn insert_object_property<T: ?Sized + JsonSchema>(
127 obj: &mut ObjectValidation,
128 key: &str,
129 has_default: bool,
130 required: bool,
131 schema: Schema,
132) {
133 obj.properties.insert(key.to_owned(), schema);
134 if !has_default && (required || !T::_schemars_private_is_option()) {
135 obj.required.insert(key.to_owned());
136 }
137}
138
139pub mod metadata {
140 use crate::Schema;
141 use serde_json::Value;
142
143 macro_rules! add_metadata_fn {
144 ($method:ident, $name:ident, $ty:ty) => {
145 pub fn $method(schema: Schema, $name: impl Into<$ty>) -> Schema {
146 let value = $name.into();
147 if value == <$ty>::default() {
148 schema
149 } else {
150 let mut schema_obj = schema.into_object();
151 schema_obj.metadata().$name = value.into();
152 Schema::Object(schema_obj)
153 }
154 }
155 };
156 }
157
158 add_metadata_fn!(add_description, description, String);
159 add_metadata_fn!(add_id, id, String);
160 add_metadata_fn!(add_title, title, String);
161 add_metadata_fn!(add_deprecated, deprecated, bool);
162 add_metadata_fn!(add_read_only, read_only, bool);
163 add_metadata_fn!(add_write_only, write_only, bool);
164 add_metadata_fn!(add_default, default, Option<Value>);
165
166 pub fn add_examples<I: IntoIterator<Item = Value>>(schema: Schema, examples: I) -> Schema {
167 let mut schema_obj = schema.into_object();
168 schema_obj.metadata().examples.extend(examples);
169 Schema::Object(schema_obj)
170 }
171}