1use serde::ser::{SerializeMap, SerializeSeq};
2use serde::{Serialize, Serializer};
3use uuid::Uuid;
4
5use crate::FiniteF64;
6use crate::annotated::{Annotated, MetaMap, MetaTree};
7use crate::macros::derive_string_meta_structure;
8use crate::meta::{Error, Meta};
9use crate::traits::{Empty, FromValue, IntoValue, SkipSerialization};
10use crate::value::{Array, Map, Object, Value};
11
12#[doc(hidden)]
14pub struct SerializePayload<'a, T>(pub &'a Annotated<T>, pub SkipSerialization);
15
16impl<T: IntoValue> Serialize for SerializePayload<'_, T> {
17 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
18 where
19 S: Serializer,
20 {
21 match self.0.value() {
22 Some(value) => value.serialize_payload(serializer, self.1),
23 None => serializer.serialize_unit(),
24 }
25 }
26}
27
28macro_rules! derive_from_value {
29 ($type:ident, $meta_type:ident, $expectation:expr) => {
30 impl FromValue for $type {
31 fn from_value(value: Annotated<Value>) -> Annotated<Self> {
32 match value {
33 Annotated(Some(Value::$meta_type(value)), meta) => Annotated(Some(value), meta),
34 Annotated(None, meta) => Annotated(None, meta),
35 Annotated(Some(value), mut meta) => {
36 meta.add_error(Error::expected($expectation));
37 meta.set_original_value(Some(value));
38 Annotated(None, meta)
39 }
40 }
41 }
42 }
43 };
44}
45
46macro_rules! derive_to_value {
47 ($type:ident, $meta_type:ident) => {
48 impl IntoValue for $type {
49 fn into_value(self) -> Value {
50 Value::$meta_type(self)
51 }
52
53 fn serialize_payload<S>(
54 &self,
55 s: S,
56 _behavior: SkipSerialization,
57 ) -> Result<S::Ok, S::Error>
58 where
59 Self: Sized,
60 S: Serializer,
61 {
62 self.serialize(s)
63 }
64 }
65 };
66}
67
68macro_rules! derive_numeric_meta_structure {
69 ($type:ident, $meta_type:ident, $expectation:expr) => {
70 impl FromValue for $type {
71 fn from_value(value: Annotated<Value>) -> Annotated<Self> {
72 value.and_then(|value| {
73 let number = match value {
74 Value::U64(x) => num_traits::cast(x),
75 Value::I64(x) => num_traits::cast(x),
76 Value::F64(x) => num_traits::cast(x),
77 _ => None,
78 };
79
80 match number {
81 Some(x) => Annotated::new(x),
82 None => {
83 let mut meta = Meta::default();
84 meta.add_error(Error::expected($expectation));
85 meta.set_original_value(Some(value));
86 Annotated(None, meta)
87 }
88 }
89 })
90 }
91 }
92
93 derive_to_value!($type, $meta_type);
94 };
95}
96
97impl Empty for String {
98 #[inline]
99 fn is_empty(&self) -> bool {
100 self.is_empty()
101 }
102}
103
104derive_from_value!(String, String, "a string");
105derive_to_value!(String, String);
106
107impl Empty for bool {
108 #[inline]
109 fn is_empty(&self) -> bool {
110 false
111 }
112}
113
114derive_from_value!(bool, Bool, "a boolean");
115derive_to_value!(bool, Bool);
116
117derive_numeric_meta_structure!(u64, U64, "an unsigned integer");
118derive_numeric_meta_structure!(i64, I64, "a signed integer");
119derive_numeric_meta_structure!(f64, F64, "a floating point number");
120
121impl FromValue for FiniteF64 {
122 fn from_value(value: Annotated<Value>) -> Annotated<Self> {
123 value.and_then(|value| {
124 let number: Option<f64> = match value {
125 Value::U64(x) => num_traits::cast(x),
126 Value::I64(x) => num_traits::cast(x),
127 Value::F64(x) => num_traits::cast(x),
128 _ => None,
129 };
130
131 match number.and_then(FiniteF64::new) {
132 Some(x) => Annotated::new(x),
133 None => {
134 let mut meta = Meta::default();
135 meta.add_error(Error::expected("a finite floating point number"));
136 meta.set_original_value(Some(value));
137 Annotated(None, meta)
138 }
139 }
140 })
141 }
142}
143
144impl IntoValue for FiniteF64 {
145 fn into_value(self) -> Value {
146 Value::F64(self.to_f64())
147 }
148
149 fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
150 where
151 Self: Sized,
152 S: Serializer,
153 {
154 self.serialize(s)
155 }
156}
157
158impl Empty for u64 {
159 #[inline]
160 fn is_empty(&self) -> bool {
161 false
162 }
163}
164
165impl Empty for i64 {
166 #[inline]
167 fn is_empty(&self) -> bool {
168 false
169 }
170}
171
172impl Empty for f64 {
173 #[inline]
174 fn is_empty(&self) -> bool {
175 false
176 }
177}
178
179impl Empty for FiniteF64 {
180 #[inline]
181 fn is_empty(&self) -> bool {
182 self.to_f64().is_empty()
183 }
184}
185
186derive_string_meta_structure!(Uuid, "a uuid");
187
188impl<T> Empty for &'_ T
189where
190 T: Empty,
191{
192 #[inline]
193 fn is_empty(&self) -> bool {
194 (*self).is_empty()
195 }
196
197 #[inline]
198 fn is_deep_empty(&self) -> bool {
199 (*self).is_deep_empty()
200 }
201}
202
203impl<T> Empty for Option<T>
204where
205 T: Empty,
206{
207 #[inline]
208 fn is_empty(&self) -> bool {
209 self.as_ref().is_none_or(Empty::is_empty)
210 }
211
212 #[inline]
213 fn is_deep_empty(&self) -> bool {
214 self.as_ref().is_none_or(Empty::is_deep_empty)
215 }
216}
217
218impl<T> Empty for Array<T>
219where
220 T: Empty,
221{
222 #[inline]
223 fn is_empty(&self) -> bool {
224 self.is_empty()
225 }
226
227 fn is_deep_empty(&self) -> bool {
228 self.iter().all(Empty::is_deep_empty)
229 }
230}
231
232impl<T> FromValue for Array<T>
233where
234 T: FromValue,
235{
236 fn from_value(value: Annotated<Value>) -> Annotated<Self> {
237 match value {
238 Annotated(Some(Value::Array(items)), meta) => Annotated(
239 Some(items.into_iter().map(FromValue::from_value).collect()),
240 meta,
241 ),
242 Annotated(None, meta) => Annotated(None, meta),
243 Annotated(Some(value), mut meta) => {
244 meta.add_error(Error::expected("an array"));
245 meta.set_original_value(Some(value));
246 Annotated(None, meta)
247 }
248 }
249 }
250}
251
252impl<T> IntoValue for Array<T>
253where
254 T: IntoValue,
255{
256 fn into_value(self) -> Value {
257 Value::Array(
258 self.into_iter()
259 .map(|x| Annotated::map_value(x, IntoValue::into_value))
260 .collect(),
261 )
262 }
263
264 fn serialize_payload<S>(&self, s: S, behavior: SkipSerialization) -> Result<S::Ok, S::Error>
265 where
266 Self: Sized,
267 S: Serializer,
268 {
269 let behavior = behavior.descend();
270 let mut seq_ser = s.serialize_seq(Some(self.len()))?;
271 for item in self {
272 if !item.skip_serialization(behavior) {
273 seq_ser.serialize_element(&SerializePayload(item, behavior))?;
274 }
275 }
276 seq_ser.end()
277 }
278
279 fn extract_child_meta(&self) -> MetaMap
280 where
281 Self: Sized,
282 {
283 let mut children = MetaMap::new();
284 for (idx, item) in self.iter().enumerate() {
285 let tree = IntoValue::extract_meta_tree(item);
286 if !tree.is_empty() {
287 children.insert(idx.to_string(), tree);
288 }
289 }
290 children
291 }
292}
293
294impl<T> Empty for Object<T>
295where
296 T: Empty,
297{
298 #[inline]
299 fn is_empty(&self) -> bool {
300 self.is_empty()
301 }
302
303 fn is_deep_empty(&self) -> bool {
304 self.values().all(Empty::is_deep_empty)
305 }
306}
307
308impl<T> FromValue for Object<T>
309where
310 T: FromValue,
311{
312 fn from_value(value: Annotated<Value>) -> Annotated<Self> {
313 match value {
314 Annotated(Some(Value::Object(items)), meta) => Annotated(
315 Some(
316 items
317 .into_iter()
318 .map(|(k, v)| (k, FromValue::from_value(v)))
319 .collect(),
320 ),
321 meta,
322 ),
323 Annotated(None, meta) => Annotated(None, meta),
324 Annotated(Some(value), mut meta) => {
325 meta.add_error(Error::expected("an object"));
326 meta.set_original_value(Some(value));
327 Annotated(None, meta)
328 }
329 }
330 }
331}
332
333impl<T> IntoValue for Object<T>
334where
335 T: IntoValue,
336{
337 fn into_value(self) -> Value {
338 Value::Object(
339 self.into_iter()
340 .map(|(k, v)| (k, Annotated::map_value(v, IntoValue::into_value)))
341 .collect(),
342 )
343 }
344
345 fn serialize_payload<S>(&self, s: S, behavior: SkipSerialization) -> Result<S::Ok, S::Error>
346 where
347 Self: Sized,
348 S: Serializer,
349 {
350 let behavior = behavior.descend();
351 let mut map_ser = s.serialize_map(Some(self.len()))?;
352 for (key, value) in self {
353 if !value.skip_serialization(behavior) {
354 map_ser.serialize_key(&key)?;
355 map_ser.serialize_value(&SerializePayload(value, behavior))?;
356 }
357 }
358 map_ser.end()
359 }
360
361 fn extract_child_meta(&self) -> Map<String, MetaTree>
362 where
363 Self: Sized,
364 {
365 let mut children = MetaMap::new();
366 for (key, value) in self.iter() {
367 let tree = IntoValue::extract_meta_tree(value);
368 if !tree.is_empty() {
369 children.insert(key.to_string(), tree);
370 }
371 }
372 children
373 }
374}
375
376impl Empty for Value {
377 fn is_empty(&self) -> bool {
378 match self {
379 Value::Bool(_) => false,
380 Value::I64(_) => false,
381 Value::U64(_) => false,
382 Value::F64(_) => false,
383 Value::String(v) => v.is_empty(),
384 Value::Array(v) => v.is_empty(),
385 Value::Object(v) => v.is_empty(),
386 }
387 }
388
389 fn is_deep_empty(&self) -> bool {
390 match self {
391 Value::Bool(_) => false,
392 Value::I64(_) => false,
393 Value::U64(_) => false,
394 Value::F64(_) => false,
395 Value::String(v) => v.is_deep_empty(),
396 Value::Array(v) => v.is_deep_empty(),
397 Value::Object(v) => v.is_deep_empty(),
398 }
399 }
400}
401
402impl FromValue for Value {
403 #[inline]
404 fn from_value(value: Annotated<Value>) -> Annotated<Value> {
405 value
406 }
407}
408
409impl IntoValue for Value {
410 fn into_value(self) -> Value {
411 self
412 }
413
414 fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
415 where
416 Self: Sized,
417 S: Serializer,
418 {
419 Serialize::serialize(self, s)
420 }
421
422 fn extract_child_meta(&self) -> Map<String, MetaTree>
423 where
424 Self: Sized,
425 {
426 let mut children = MetaMap::new();
427 match self {
428 Value::Object(items) => {
429 for (key, value) in items.iter() {
430 let tree = IntoValue::extract_meta_tree(value);
431 if !tree.is_empty() {
432 children.insert(key.to_string(), tree);
433 }
434 }
435 }
436 Value::Array(items) => {
437 for (idx, item) in items.iter().enumerate() {
438 let tree = IntoValue::extract_meta_tree(item);
439 if !tree.is_empty() {
440 children.insert(idx.to_string(), tree);
441 }
442 }
443 }
444 _ => {}
445 }
446 children
447 }
448}
449
450impl<T> FromValue for Box<T>
451where
452 T: FromValue,
453{
454 fn from_value(value: Annotated<Value>) -> Annotated<Self>
455 where
456 Self: Sized,
457 {
458 let annotated: Annotated<T> = FromValue::from_value(value);
459 Annotated(annotated.0.map(Box::new), annotated.1)
460 }
461}
462
463impl<T> IntoValue for Box<T>
464where
465 T: IntoValue,
466{
467 fn into_value(self) -> Value
468 where
469 Self: Sized,
470 {
471 IntoValue::into_value(*self)
472 }
473
474 fn extract_child_meta(&self) -> MetaMap
475 where
476 Self: Sized,
477 {
478 IntoValue::extract_child_meta(&**self)
479 }
480
481 fn serialize_payload<S>(&self, s: S, behavior: SkipSerialization) -> Result<S::Ok, S::Error>
482 where
483 Self: Sized,
484 S: Serializer,
485 {
486 IntoValue::serialize_payload(&**self, s, behavior)
487 }
488}
489
490impl<T> Empty for Box<T>
491where
492 T: Empty,
493{
494 #[inline]
495 fn is_empty(&self) -> bool {
496 self.as_ref().is_empty()
497 }
498
499 #[inline]
500 fn is_deep_empty(&self) -> bool {
501 self.as_ref().is_deep_empty()
502 }
503}
504
505impl<T> Empty for Annotated<T>
507where
508 T: Empty,
509{
510 fn is_empty(&self) -> bool {
519 self.skip_serialization(SkipSerialization::Empty(false))
520 }
521
522 fn is_deep_empty(&self) -> bool {
524 self.skip_serialization(SkipSerialization::Empty(true))
525 }
526}
527
528macro_rules! tuple_meta_structure {
529 ($count: literal, $($name: ident),+) => {
530 impl< $( $name: FromValue ),* > FromValue for ( $( Annotated<$name>, )* ) {
531 #[allow(non_snake_case, unused_variables)]
532 fn from_value(annotated: Annotated<Value>) -> Annotated<Self> {
533 let expectation = match $count {
534 1 => "a single element",
535 2 => "a tuple",
536 _ => concat!("a ", $count, "-tuple"),
537 };
538
539 let mut n = 0;
540 $(let $name = (); n += 1;)*
541 match annotated {
542 Annotated(Some(Value::Array(items)), mut meta) => {
543 if items.len() != n {
544 meta.add_error(Error::expected(expectation));
545 meta.set_original_value(Some(items));
546 return Annotated(None, meta);
547 }
548
549 let mut iter = items.into_iter();
550 Annotated(Some((
551 $({
552 let $name = ();
553 FromValue::from_value(iter.next().unwrap())
554 },)*
555 )), meta)
556 }
557 Annotated(Some(value), mut meta) => {
558 meta.add_error(Error::expected(expectation));
559 meta.set_original_value(Some(value));
560 Annotated(None, meta)
561 }
562 Annotated(None, meta) => Annotated(None, meta)
563 }
564 }
565 }
566
567 impl< $( $name: IntoValue ),* > IntoValue for ( $( Annotated<$name>, )* ) {
568 #[allow(non_snake_case, unused_variables)]
569 fn into_value(self) -> Value {
570 let ($($name,)*) = self;
571 Value::Array(vec![$(Annotated::map_value($name, IntoValue::into_value),)*])
572 }
573
574 #[allow(non_snake_case, unused_variables)]
575 fn serialize_payload<S>(&self, s: S, behavior: crate::traits::SkipSerialization) -> Result<S::Ok, S::Error>
576 where
577 S: Serializer,
578 {
579 let behavior = behavior.descend();
580 let mut s = s.serialize_seq(None)?;
581 let ($($name,)*) = self;
582 $(s.serialize_element(&SerializePayload($name, behavior))?;)*
583 s.end()
584 }
585
586 #[allow(non_snake_case, unused_variables, unused_assignments)]
587 fn extract_child_meta(&self) -> MetaMap
588 where
589 Self: Sized,
590 {
591 let mut children = MetaMap::new();
592 let ($($name,)*) = self;
593 let mut idx = 0;
594 $({
595 let tree = IntoValue::extract_meta_tree($name);
596 if !tree.is_empty() {
597 children.insert(idx.to_string(), tree);
598 }
599 idx += 1;
600 })*;
601 children
602 }
603 }
604
605 impl< $( $name: Empty ),* > Empty for ( $( Annotated<$name>, )* ) {
606 #[inline]
607 fn is_empty(&self) -> bool {
608 false
609 }
610
611 #[inline]
612 #[allow(non_snake_case)]
613 fn is_deep_empty(&self) -> bool {
614 let ($($name,)*) = self;
615 true $(&& $name.is_deep_empty())*
616 }
617 }
618 }
619}
620
621tuple_meta_structure!(1, T1);
622tuple_meta_structure!(2, T1, T2);
623tuple_meta_structure!(3, T1, T2, T3);
624tuple_meta_structure!(4, T1, T2, T3, T4);
625tuple_meta_structure!(5, T1, T2, T3, T4, T5);
626tuple_meta_structure!(6, T1, T2, T3, T4, T5, T6);
627tuple_meta_structure!(7, T1, T2, T3, T4, T5, T6, T7);
628tuple_meta_structure!(8, T1, T2, T3, T4, T5, T6, T7, T8);
629tuple_meta_structure!(9, T1, T2, T3, T4, T5, T6, T7, T8, T9);
630tuple_meta_structure!(10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
631tuple_meta_structure!(11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
632tuple_meta_structure!(12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);