relay_protocol/
impls.rs

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// This needs to be public because the derive crate emits it
12#[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
460/// Checks whether annotated data contains either a value or meta data.
461impl<T> Empty for Annotated<T>
462where
463    T: Empty,
464{
465    /// Returns if this object contains data to be serialized.
466    ///
467    /// **Caution:** This has different behavior than `annotated.value().is_empty()`! Annotated is
468    /// **not** empty if there is meta data that needs to be serialized. This is in line with the
469    /// derived implementation of `Empty` on structs, which calls `Annotated::is_empty` on every
470    /// child.
471    ///
472    /// To check if a value is missing or empty, use `Option::is_empty` on the value instead.
473    fn is_empty(&self) -> bool {
474        self.skip_serialization(SkipSerialization::Empty(false))
475    }
476
477    /// Returns if this object contains nested data to be serialized.
478    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);