relay_protocol/
annotated.rs

1use std::fmt;
2
3use serde::ser::SerializeMap;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6use crate::meta::{Error, Meta};
7use crate::traits::{Empty, FromValue, IntoValue, SkipSerialization};
8use crate::value::{Map, Value};
9
10/// Represents a tree of meta objects.
11#[derive(Default, Debug, Serialize)]
12pub struct MetaTree {
13    /// The node's meta data
14    #[serde(rename = "", skip_serializing_if = "Meta::is_empty")]
15    pub meta: Meta,
16
17    /// References to the children.
18    #[serde(flatten)]
19    pub children: MetaMap,
20}
21
22impl MetaTree {
23    fn from_value(value: Annotated<Value>) -> Self {
24        match value {
25            Annotated(Some(Value::Object(mut map)), _) => MetaTree {
26                meta: map
27                    .remove("")
28                    .and_then(|value| {
29                        // this is not the fastest operation because we cannot currently
30                        // deserialize stright from a `Value`.  However since we expect
31                        // to handle very few meta data initially this is okay enough
32                        let value: serde_json::Value = value.into();
33                        serde_json::from_value(value).ok()
34                    })
35                    .unwrap_or_default(),
36                children: map
37                    .into_iter()
38                    .map(|(k, v)| (k, MetaTree::from_value(v)))
39                    .collect(),
40            },
41            _ => MetaTree::default(),
42        }
43    }
44
45    /// Checks if the tree has any errors.
46    pub fn has_errors(&self) -> bool {
47        self.meta.has_errors() || self.children.values().any(MetaTree::has_errors)
48    }
49
50    /// Checks if the tree is empty.
51    pub fn is_empty(&self) -> bool {
52        self.meta.is_empty() && self.children.values().all(MetaTree::is_empty)
53    }
54}
55
56/// Meta for children.
57pub type MetaMap = Map<String, MetaTree>;
58
59/// Wrapper for data fields with optional meta data.
60#[derive(Clone, PartialEq)]
61pub struct Annotated<T>(pub Option<T>, pub Meta);
62
63/// An utility to serialize annotated objects with payload.
64#[derive(Debug)]
65pub struct SerializableAnnotated<'a, T>(pub &'a Annotated<T>);
66
67impl<T: IntoValue> Serialize for SerializableAnnotated<'_, T> {
68    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69    where
70        S: Serializer,
71    {
72        self.0.serialize_with_meta(serializer)
73    }
74}
75
76/// An utility to de-serialize annotated objects with payload.
77#[derive(Debug)]
78pub struct DeserializableAnnotated<T>(pub Annotated<T>);
79
80impl<'de, T> Deserialize<'de> for DeserializableAnnotated<T>
81where
82    T: FromValue,
83{
84    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85    where
86        D: serde::de::Deserializer<'de>,
87    {
88        Ok(Self(Annotated::<T>::deserialize_with_meta(deserializer)?))
89    }
90}
91
92impl<T: fmt::Debug> fmt::Debug for Annotated<T> {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        match *self {
95            Annotated(Some(ref value), ref meta) => {
96                if meta.is_empty() {
97                    fmt::Debug::fmt(value, f)
98                } else {
99                    f.debug_tuple("Annotated").field(value).field(meta).finish()
100                }
101            }
102            Annotated(None, ref meta) => {
103                if meta.is_empty() {
104                    f.pad("~")
105                } else {
106                    fmt::Debug::fmt(meta, f)
107                }
108            }
109        }
110    }
111}
112
113impl<T> Annotated<T> {
114    /// Creates a new annotated value without meta data.
115    #[inline]
116    pub fn new(value: T) -> Self {
117        Annotated(Some(value), Meta::default())
118    }
119
120    /// Creates an empty annotated value without meta data.
121    #[inline]
122    pub fn empty() -> Self {
123        Annotated(None, Meta::default())
124    }
125
126    /// Creates an empty annotated value with error attached.
127    pub fn from_error<E>(err: E, value: Option<Value>) -> Self
128    where
129        E: Into<Error>,
130    {
131        Annotated(None, {
132            let mut meta = Meta::from_error(err);
133            meta.set_original_value(value);
134            meta
135        })
136    }
137
138    /// Tries to convert a `U` value into `Annotated<T>`.
139    pub fn try_from<U>(value: U) -> Self
140    where
141        T: TryFrom<U>,
142        Error: From<<T as TryFrom<U>>::Error>,
143        U: Into<Value> + Copy,
144    {
145        match value.try_into() {
146            Ok(value) => Self::new(value),
147            Err(err) => Self::from_error(err, Some(value.into())),
148        }
149    }
150
151    /// Returns a reference to the value.
152    ///
153    /// Returns `None` if this value is not initialized, missing, or invalid.
154    #[inline]
155    pub fn value(&self) -> Option<&T> {
156        self.0.as_ref()
157    }
158
159    /// Returns a mutable reference to the value.
160    ///
161    /// Returns `None` if this value is not initialized, missing, or invalid.
162    #[inline]
163    pub fn value_mut(&mut self) -> &mut Option<T> {
164        &mut self.0
165    }
166
167    /// Replaces the stored value.
168    #[inline]
169    pub fn set_value(&mut self, value: Option<T>) {
170        self.0 = value;
171    }
172
173    /// Returns a reference to the meta data attached to this value.
174    #[inline]
175    pub fn meta(&self) -> &Meta {
176        &self.1
177    }
178
179    /// Returns a mutable reference to the meta data attached to this value.
180    #[inline]
181    pub fn meta_mut(&mut self) -> &mut Meta {
182        &mut self.1
183    }
184
185    /// Returns the stored value and drops all meta data.
186    #[inline]
187    pub fn into_value(self) -> Option<T> {
188        self.0
189    }
190
191    /// Calls `f` with the stored value if available and merges meta data into the result.
192    pub fn and_then<F, U, R>(self, f: F) -> Annotated<U>
193    where
194        F: FnOnce(T) -> R,
195        R: Into<Annotated<U>>,
196    {
197        if let Some(value) = self.0 {
198            let Annotated(value, meta) = f(value).into();
199            Annotated(value, self.1.merge(meta))
200        } else {
201            Annotated(None, self.1)
202        }
203    }
204
205    /// Maps an `Annotated<T>` to an `Annotated<U>` and keeps the original meta data.
206    pub fn map_value<U, F>(self, f: F) -> Annotated<U>
207    where
208        F: FnOnce(T) -> U,
209    {
210        Annotated(self.0.map(f), self.1)
211    }
212
213    /// Inserts a value computed from `f` into the value if it is `None`, then returns a mutable
214    /// reference to the contained value.
215    pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
216    where
217        F: FnOnce() -> T,
218    {
219        self.value_mut().get_or_insert_with(f)
220    }
221
222    /// Merges the supplied [`Annotated`] in the left [`Annotated`].
223    pub fn merge(&mut self, other: Annotated<T>, block: impl FnOnce(&mut T, T)) {
224        match (self.value_mut(), other.into_value()) {
225            (Some(left), Some(right)) => block(left, right),
226            (None, Some(right)) => self.set_value(Some(right)),
227            _ => {}
228        }
229    }
230
231    /// Returns `self` if it contains a value, otherwise computes and returns `other`.
232    pub fn or_else<F: FnOnce() -> Annotated<T>>(self, other: F) -> Annotated<T> {
233        if self.value().is_some() {
234            return self;
235        }
236
237        other()
238    }
239}
240
241impl<T> Annotated<Option<T>> {
242    /// Transposes an `Annotated` of [`Option`] into a [`Option`] of `Annotated`.
243    pub fn transpose(self) -> Option<Annotated<T>> {
244        match self {
245            Annotated(Some(Some(value)), meta) => Some(Annotated(Some(value), meta)),
246            Annotated(Some(None), _) => None,
247            Annotated(None, meta) => Some(Annotated(None, meta)),
248        }
249    }
250}
251
252impl<T> Annotated<T>
253where
254    T: AsRef<str>,
255{
256    /// Returns a reference to the string value if set.
257    #[inline]
258    pub fn as_str(&self) -> Option<&str> {
259        self.value().map(AsRef::as_ref)
260    }
261}
262
263impl Annotated<Value> {
264    /// Returns a reference to the string value if this value is a string and it is set.
265    #[inline]
266    pub fn as_str(&self) -> Option<&str> {
267        self.value().and_then(Value::as_str)
268    }
269}
270
271impl<T> Annotated<T>
272where
273    T: Empty,
274{
275    /// Returns whether this value should be skipped during serialization.
276    ///
277    /// An `Annotated<T>` is always serialized if it has meta data. Otherwise, serialization
278    /// depends on the behavior. For `SkipSerialization::Empty`, the `Empty` trait is used to
279    /// determine emptiness of the contained value and defaults to `false` for no value.
280    pub fn skip_serialization(&self, behavior: SkipSerialization) -> bool {
281        if !self.meta().is_empty() {
282            return false;
283        }
284
285        match behavior {
286            SkipSerialization::Never => false,
287            SkipSerialization::Null(_) => self.value().is_none(),
288            SkipSerialization::Empty(false) => self.value().is_none_or(Empty::is_empty),
289            SkipSerialization::Empty(true) => self.value().is_none_or(Empty::is_deep_empty),
290        }
291    }
292}
293
294impl<T> Annotated<T>
295where
296    T: FromValue,
297{
298    /// Deserializes an annotated from a deserializer
299    pub fn deserialize_with_meta<'de, D: Deserializer<'de>>(
300        deserializer: D,
301    ) -> Result<Self, D::Error> {
302        Ok(FromValue::from_value(
303            match Option::<Value>::deserialize(deserializer)? {
304                Some(Value::Object(mut map)) => {
305                    let meta_tree = map
306                        .remove("_meta")
307                        .map(MetaTree::from_value)
308                        .unwrap_or_default();
309
310                    let mut value: Annotated<Value> = Annotated::new(Value::Object(map));
311                    value.attach_meta_tree(meta_tree);
312                    value
313                }
314                other => Annotated::from(other),
315            },
316        ))
317    }
318
319    /// Deserializes an annotated from a JSON string.
320    pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
321        Self::deserialize_with_meta(&mut serde_json::Deserializer::from_str(s))
322    }
323
324    /// Deserializes an annotated from JSON bytes.
325    pub fn from_json_bytes(b: &[u8]) -> Result<Self, serde_json::Error> {
326        Self::deserialize_with_meta(&mut serde_json::Deserializer::from_slice(b))
327    }
328}
329
330impl<T> Annotated<T>
331where
332    T: IntoValue,
333{
334    /// Serializes an annotated value into a serializer.
335    pub fn serialize_with_meta<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
336        let mut map_ser = serializer.serialize_map(None)?;
337        let meta_tree = IntoValue::extract_meta_tree(self);
338
339        if let Some(value) = self.value() {
340            // NOTE: This is a hack and known to be instable use of serde.
341            use serde::__private228::ser::FlatMapSerializer;
342            IntoValue::serialize_payload(
343                value,
344                FlatMapSerializer(&mut map_ser),
345                SkipSerialization::default(),
346            )?;
347        }
348
349        if !meta_tree.is_empty() {
350            map_ser.serialize_key("_meta")?;
351            map_ser.serialize_value(&meta_tree)?;
352        }
353        map_ser.end()
354    }
355
356    /// Serializes an annotated value into a JSON string.
357    pub fn to_json(&self) -> Result<String, serde_json::Error> {
358        let mut ser = serde_json::Serializer::new(Vec::with_capacity(128));
359        self.serialize_with_meta(&mut ser)?;
360        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
361    }
362
363    /// Serializes an annotated value into a pretty JSON string.
364    pub fn to_json_pretty(&self) -> Result<String, serde_json::Error> {
365        let mut ser = serde_json::Serializer::pretty(Vec::with_capacity(128));
366        self.serialize_with_meta(&mut ser)?;
367        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
368    }
369
370    /// Serializes an annotated value into a JSON string.
371    pub fn payload_to_json(&self) -> Result<String, serde_json::Error> {
372        let mut ser = serde_json::Serializer::new(Vec::with_capacity(128));
373
374        match self.value() {
375            Some(value) => {
376                IntoValue::serialize_payload(value, &mut ser, SkipSerialization::default())?
377            }
378            None => ser.serialize_unit()?,
379        }
380
381        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
382    }
383
384    /// Serializes an annotated value into a pretty JSON string.
385    pub fn payload_to_json_pretty(&self) -> Result<String, serde_json::Error> {
386        let mut ser = serde_json::Serializer::pretty(Vec::with_capacity(128));
387
388        match self.value() {
389            Some(value) => {
390                IntoValue::serialize_payload(value, &mut ser, SkipSerialization::default())?
391            }
392            None => ser.serialize_unit()?,
393        }
394
395        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
396    }
397}
398
399impl Annotated<Value> {
400    fn attach_meta_tree(&mut self, mut meta_tree: MetaTree) {
401        match self.value_mut() {
402            Some(Value::Array(items)) => {
403                for (idx, item) in items.iter_mut().enumerate() {
404                    if let Some(meta_tree) = meta_tree.children.remove(&idx.to_string()) {
405                        item.attach_meta_tree(meta_tree);
406                    }
407                }
408            }
409            Some(Value::Object(items)) => {
410                for (key, value) in items.iter_mut() {
411                    if let Some(meta_tree) = meta_tree.children.remove(key) {
412                        value.attach_meta_tree(meta_tree);
413                    }
414                }
415            }
416            _ => {}
417        }
418
419        *self.meta_mut() = meta_tree.meta;
420    }
421}
422
423impl<T> From<T> for Annotated<T> {
424    fn from(t: T) -> Self {
425        Annotated::new(t)
426    }
427}
428
429impl<T> From<Option<T>> for Annotated<T> {
430    fn from(option: Option<T>) -> Self {
431        Annotated(option, Meta::default())
432    }
433}
434
435impl<T> From<Result<T, Error>> for Annotated<T> {
436    fn from(t: Result<T, Error>) -> Self {
437        t.map_or_else(|err| Annotated::from_error(err, None), Annotated::new)
438    }
439}
440
441impl<T> Default for Annotated<T> {
442    fn default() -> Annotated<T> {
443        Annotated::empty()
444    }
445}