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