1use crate::schema::*;
2use crate::JsonSchema;
3use crate::{gen::SchemaGenerator, Map};
4use serde_json::{Error, Value};
5use std::{convert::TryInto, fmt::Display};
6
7pub(crate) struct Serializer<'a> {
8 pub(crate) gen: &'a mut SchemaGenerator,
9 pub(crate) include_title: bool,
10}
11
12pub(crate) struct SerializeSeq<'a> {
13 gen: &'a mut SchemaGenerator,
14 items: Option<Schema>,
15}
16
17pub(crate) struct SerializeTuple<'a> {
18 gen: &'a mut SchemaGenerator,
19 items: Vec<Schema>,
20 title: &'static str,
21}
22
23pub(crate) struct SerializeMap<'a> {
24 gen: &'a mut SchemaGenerator,
25 properties: Map<String, Schema>,
26 current_key: Option<String>,
27 title: &'static str,
28}
29
30macro_rules! forward_to_subschema_for {
31 ($fn:ident, $ty:ty) => {
32 fn $fn(self, _value: $ty) -> Result<Self::Ok, Self::Error> {
33 Ok(self.gen.subschema_for::<$ty>())
34 }
35 };
36}
37
38macro_rules! return_instance_type {
39 ($fn:ident, $ty:ty, $instance_type:ident) => {
40 fn $fn(self, _value: $ty) -> Result<Self::Ok, Self::Error> {
41 Ok(SchemaObject {
42 instance_type: Some(InstanceType::$instance_type.into()),
43 ..Default::default()
44 }
45 .into())
46 }
47 };
48}
49
50impl<'a> serde::Serializer for Serializer<'a> {
51 type Ok = Schema;
52 type Error = Error;
53
54 type SerializeSeq = SerializeSeq<'a>;
55 type SerializeTuple = SerializeTuple<'a>;
56 type SerializeTupleStruct = SerializeTuple<'a>;
57 type SerializeTupleVariant = Self;
58 type SerializeMap = SerializeMap<'a>;
59 type SerializeStruct = SerializeMap<'a>;
60 type SerializeStructVariant = Self;
61
62 return_instance_type!(serialize_i8, i8, Integer);
63 return_instance_type!(serialize_i16, i16, Integer);
64 return_instance_type!(serialize_i32, i32, Integer);
65 return_instance_type!(serialize_i64, i64, Integer);
66 return_instance_type!(serialize_i128, i128, Integer);
67 return_instance_type!(serialize_u8, u8, Integer);
68 return_instance_type!(serialize_u16, u16, Integer);
69 return_instance_type!(serialize_u32, u32, Integer);
70 return_instance_type!(serialize_u64, u64, Integer);
71 return_instance_type!(serialize_u128, u128, Integer);
72 return_instance_type!(serialize_f32, f32, Number);
73 return_instance_type!(serialize_f64, f64, Number);
74
75 forward_to_subschema_for!(serialize_bool, bool);
76 forward_to_subschema_for!(serialize_char, char);
77 forward_to_subschema_for!(serialize_str, &str);
78 forward_to_subschema_for!(serialize_bytes, &[u8]);
79
80 fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
81 where
82 T: Display,
83 {
84 Ok(self.gen.subschema_for::<&str>())
85 }
86
87 fn collect_map<K, V, I>(self, iter: I) -> Result<Self::Ok, Self::Error>
88 where
89 K: serde::Serialize,
90 V: serde::Serialize,
91 I: IntoIterator<Item = (K, V)>,
92 {
93 let value_schema = iter
94 .into_iter()
95 .try_fold(None, |acc, (_, v)| {
96 if acc == Some(Schema::Bool(true)) {
97 return Ok(acc);
98 }
99
100 let schema = v.serialize(Serializer {
101 gen: self.gen,
102 include_title: false,
103 })?;
104 Ok(match &acc {
105 None => Some(schema),
106 Some(items) if items != &schema => Some(Schema::Bool(true)),
107 _ => acc,
108 })
109 })?
110 .unwrap_or(Schema::Bool(true));
111
112 Ok(SchemaObject {
113 instance_type: Some(InstanceType::Object.into()),
114 object: Some(Box::new(ObjectValidation {
115 additional_properties: Some(Box::new(value_schema)),
116 ..ObjectValidation::default()
117 })),
118 ..SchemaObject::default()
119 }
120 .into())
121 }
122
123 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
124 Ok(self.gen.subschema_for::<Option<Value>>())
125 }
126
127 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
128 self.serialize_none()
129 }
130
131 fn serialize_some<T: ?Sized>(mut self, value: &T) -> Result<Self::Ok, Self::Error>
132 where
133 T: serde::Serialize,
134 {
135 fn add_null_type(instance_type: &mut SingleOrVec<InstanceType>) {
137 match instance_type {
138 SingleOrVec::Single(ty) if **ty != InstanceType::Null => {
139 *instance_type = vec![**ty, InstanceType::Null].into()
140 }
141 SingleOrVec::Vec(ty) if !ty.contains(&InstanceType::Null) => {
142 ty.push(InstanceType::Null)
143 }
144 _ => {}
145 };
146 }
147
148 let mut schema = value.serialize(Serializer {
149 gen: self.gen,
150 include_title: false,
151 })?;
152
153 if self.gen.settings().option_add_null_type {
154 schema = match schema {
155 Schema::Bool(true) => Schema::Bool(true),
156 Schema::Bool(false) => <()>::json_schema(&mut self.gen),
157 Schema::Object(SchemaObject {
158 instance_type: Some(ref mut instance_type),
159 ..
160 }) => {
161 add_null_type(instance_type);
162 schema
163 }
164 schema => SchemaObject {
165 subschemas: Some(Box::new(SubschemaValidation {
166 any_of: Some(vec![schema, <()>::json_schema(&mut self.gen)]),
167 ..Default::default()
168 })),
169 ..Default::default()
170 }
171 .into(),
172 }
173 }
174
175 if self.gen.settings().option_nullable {
176 let mut schema_obj = schema.into_object();
177 schema_obj
178 .extensions
179 .insert("nullable".to_owned(), serde_json::json!(true));
180 schema = Schema::Object(schema_obj);
181 };
182
183 Ok(schema)
184 }
185
186 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
187 Ok(self.gen.subschema_for::<()>())
188 }
189
190 fn serialize_unit_variant(
191 self,
192 _name: &'static str,
193 _variant_index: u32,
194 _variant: &'static str,
195 ) -> Result<Self::Ok, Self::Error> {
196 Ok(Schema::Bool(true))
197 }
198
199 fn serialize_newtype_struct<T: ?Sized>(
200 self,
201 name: &'static str,
202 value: &T,
203 ) -> Result<Self::Ok, Self::Error>
204 where
205 T: serde::Serialize,
206 {
207 let include_title = self.include_title;
208 let mut result = value.serialize(self);
209
210 if include_title {
211 if let Ok(Schema::Object(ref mut object)) = result {
212 object.metadata().title = Some(name.to_string());
213 }
214 }
215
216 result
217 }
218
219 fn serialize_newtype_variant<T: ?Sized>(
220 self,
221 _name: &'static str,
222 _variant_index: u32,
223 _variant: &'static str,
224 _value: &T,
225 ) -> Result<Self::Ok, Self::Error>
226 where
227 T: serde::Serialize,
228 {
229 Ok(Schema::Bool(true))
230 }
231
232 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
233 Ok(SerializeSeq {
234 gen: self.gen,
235 items: None,
236 })
237 }
238
239 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
240 Ok(SerializeTuple {
241 gen: self.gen,
242 items: Vec::with_capacity(len),
243 title: "",
244 })
245 }
246
247 fn serialize_tuple_struct(
248 self,
249 name: &'static str,
250 len: usize,
251 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
252 let title = if self.include_title { name } else { "" };
253 Ok(SerializeTuple {
254 gen: self.gen,
255 items: Vec::with_capacity(len),
256 title,
257 })
258 }
259
260 fn serialize_tuple_variant(
261 self,
262 _name: &'static str,
263 _variant_index: u32,
264 _variant: &'static str,
265 _len: usize,
266 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
267 Ok(self)
268 }
269
270 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
271 Ok(SerializeMap {
272 gen: self.gen,
273 properties: Map::new(),
274 current_key: None,
275 title: "",
276 })
277 }
278
279 fn serialize_struct(
280 self,
281 name: &'static str,
282 _len: usize,
283 ) -> Result<Self::SerializeStruct, Self::Error> {
284 let title = if self.include_title { name } else { "" };
285 Ok(SerializeMap {
286 gen: self.gen,
287 properties: Map::new(),
288 current_key: None,
289 title,
290 })
291 }
292
293 fn serialize_struct_variant(
294 self,
295 _name: &'static str,
296 _variant_index: u32,
297 _variant: &'static str,
298 _len: usize,
299 ) -> Result<Self::SerializeStructVariant, Self::Error> {
300 Ok(self)
301 }
302}
303
304impl serde::ser::SerializeTupleVariant for Serializer<'_> {
305 type Ok = Schema;
306 type Error = Error;
307
308 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
309 where
310 T: serde::Serialize,
311 {
312 Ok(())
313 }
314
315 fn end(self) -> Result<Self::Ok, Self::Error> {
316 Ok(Schema::Bool(true))
317 }
318}
319
320impl serde::ser::SerializeStructVariant for Serializer<'_> {
321 type Ok = Schema;
322 type Error = Error;
323
324 fn serialize_field<T: ?Sized>(
325 &mut self,
326 _key: &'static str,
327 _value: &T,
328 ) -> Result<(), Self::Error>
329 where
330 T: serde::Serialize,
331 {
332 Ok(())
333 }
334
335 fn end(self) -> Result<Self::Ok, Self::Error> {
336 Ok(Schema::Bool(true))
337 }
338}
339
340impl serde::ser::SerializeSeq for SerializeSeq<'_> {
341 type Ok = Schema;
342 type Error = Error;
343
344 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
345 where
346 T: serde::Serialize,
347 {
348 if self.items != Some(Schema::Bool(true)) {
349 let schema = value.serialize(Serializer {
350 gen: self.gen,
351 include_title: false,
352 })?;
353 match &self.items {
354 None => self.items = Some(schema),
355 Some(items) => {
356 if items != &schema {
357 self.items = Some(Schema::Bool(true))
358 }
359 }
360 }
361 }
362
363 Ok(())
364 }
365
366 fn end(self) -> Result<Self::Ok, Self::Error> {
367 let items = self.items.unwrap_or(Schema::Bool(true));
368 Ok(SchemaObject {
369 instance_type: Some(InstanceType::Array.into()),
370 array: Some(Box::new(ArrayValidation {
371 items: Some(items.into()),
372 ..ArrayValidation::default()
373 })),
374 ..SchemaObject::default()
375 }
376 .into())
377 }
378}
379
380impl serde::ser::SerializeTuple for SerializeTuple<'_> {
381 type Ok = Schema;
382 type Error = Error;
383
384 fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
385 where
386 T: serde::Serialize,
387 {
388 let schema = value.serialize(Serializer {
389 gen: self.gen,
390 include_title: false,
391 })?;
392 self.items.push(schema);
393 Ok(())
394 }
395
396 fn end(self) -> Result<Self::Ok, Self::Error> {
397 let len = self.items.len().try_into().ok();
398 let mut schema = SchemaObject {
399 instance_type: Some(InstanceType::Array.into()),
400 array: Some(Box::new(ArrayValidation {
401 items: Some(SingleOrVec::Vec(self.items)),
402 max_items: len,
403 min_items: len,
404 ..ArrayValidation::default()
405 })),
406 ..SchemaObject::default()
407 };
408
409 if !self.title.is_empty() {
410 schema.metadata().title = Some(self.title.to_owned());
411 }
412
413 Ok(schema.into())
414 }
415}
416
417impl serde::ser::SerializeTupleStruct for SerializeTuple<'_> {
418 type Ok = Schema;
419 type Error = Error;
420
421 fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
422 where
423 T: serde::Serialize,
424 {
425 serde::ser::SerializeTuple::serialize_element(self, value)
426 }
427
428 fn end(self) -> Result<Self::Ok, Self::Error> {
429 serde::ser::SerializeTuple::end(self)
430 }
431}
432
433impl serde::ser::SerializeMap for SerializeMap<'_> {
434 type Ok = Schema;
435 type Error = Error;
436
437 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
438 where
439 T: serde::Serialize,
440 {
441 let json = serde_json::to_string(key)?;
444 self.current_key = Some(
445 json.trim_start_matches('"')
446 .trim_end_matches('"')
447 .to_string(),
448 );
449
450 Ok(())
451 }
452
453 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
454 where
455 T: serde::Serialize,
456 {
457 let key = self.current_key.take().unwrap_or_default();
458 let schema = value.serialize(Serializer {
459 gen: self.gen,
460 include_title: false,
461 })?;
462 self.properties.insert(key, schema);
463
464 Ok(())
465 }
466
467 fn end(self) -> Result<Self::Ok, Self::Error> {
468 let mut schema = SchemaObject {
469 instance_type: Some(InstanceType::Object.into()),
470 object: Some(Box::new(ObjectValidation {
471 properties: self.properties,
472 ..ObjectValidation::default()
473 })),
474 ..SchemaObject::default()
475 };
476
477 if !self.title.is_empty() {
478 schema.metadata().title = Some(self.title.to_owned());
479 }
480
481 Ok(schema.into())
482 }
483}
484
485impl serde::ser::SerializeStruct for SerializeMap<'_> {
486 type Ok = Schema;
487 type Error = Error;
488
489 fn serialize_field<T: ?Sized>(
490 &mut self,
491 key: &'static str,
492 value: &T,
493 ) -> Result<(), Self::Error>
494 where
495 T: serde::Serialize,
496 {
497 let prop_schema = value.serialize(Serializer {
498 gen: self.gen,
499 include_title: false,
500 })?;
501 self.properties.insert(key.to_string(), prop_schema);
502
503 Ok(())
504 }
505
506 fn end(self) -> Result<Self::Ok, Self::Error> {
507 serde::ser::SerializeMap::end(self)
508 }
509}