relay_protocol/
impls.rs

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// This needs to be public because the derive crate emits it
13#[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
505/// Checks whether annotated data contains either a value or meta data.
506impl<T> Empty for Annotated<T>
507where
508    T: Empty,
509{
510    /// Returns if this object contains data to be serialized.
511    ///
512    /// **Caution:** This has different behavior than `annotated.value().is_empty()`! Annotated is
513    /// **not** empty if there is meta data that needs to be serialized. This is in line with the
514    /// derived implementation of `Empty` on structs, which calls `Annotated::is_empty` on every
515    /// child.
516    ///
517    /// To check if a value is missing or empty, use `Option::is_empty` on the value instead.
518    fn is_empty(&self) -> bool {
519        self.skip_serialization(SkipSerialization::Empty(false))
520    }
521
522    /// Returns if this object contains nested data to be serialized.
523    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);