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