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