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