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
218impl<T> Annotated<T>
219where
220    T: AsRef<str>,
221{
222    /// Returns a reference to the string value if set.
223    #[inline]
224    pub fn as_str(&self) -> Option<&str> {
225        self.value().map(AsRef::as_ref)
226    }
227}
228
229impl Annotated<Value> {
230    /// Returns a reference to the string value if this value is a string and it is set.
231    #[inline]
232    pub fn as_str(&self) -> Option<&str> {
233        self.value().and_then(Value::as_str)
234    }
235}
236
237impl<T> Annotated<T>
238where
239    T: Empty,
240{
241    /// Returns whether this value should be skipped during serialization.
242    ///
243    /// An `Annotated<T>` is always serialized if it has meta data. Otherwise, serialization
244    /// depends on the behavior. For `SkipSerialization::Empty`, the `Empty` trait is used to
245    /// determine emptiness of the contained value and defaults to `false` for no value.
246    pub fn skip_serialization(&self, behavior: SkipSerialization) -> bool {
247        if !self.meta().is_empty() {
248            return false;
249        }
250
251        match behavior {
252            SkipSerialization::Never => false,
253            SkipSerialization::Null(_) => self.value().is_none(),
254            SkipSerialization::Empty(false) => self.value().is_none_or(Empty::is_empty),
255            SkipSerialization::Empty(true) => self.value().is_none_or(Empty::is_deep_empty),
256        }
257    }
258}
259
260impl<T> Annotated<T>
261where
262    T: FromValue,
263{
264    /// Deserializes an annotated from a deserializer
265    pub fn deserialize_with_meta<'de, D: Deserializer<'de>>(
266        deserializer: D,
267    ) -> Result<Self, D::Error> {
268        Ok(FromValue::from_value(
269            match Option::<Value>::deserialize(deserializer)? {
270                Some(Value::Object(mut map)) => {
271                    let meta_tree = map
272                        .remove("_meta")
273                        .map(MetaTree::from_value)
274                        .unwrap_or_default();
275
276                    let mut value: Annotated<Value> = Annotated::new(Value::Object(map));
277                    value.attach_meta_tree(meta_tree);
278                    value
279                }
280                other => Annotated::from(other),
281            },
282        ))
283    }
284
285    /// Deserializes an annotated from a JSON string.
286    pub fn from_json(s: &str) -> Result<Self, serde_json::Error> {
287        Self::deserialize_with_meta(&mut serde_json::Deserializer::from_str(s))
288    }
289
290    /// Deserializes an annotated from JSON bytes.
291    pub fn from_json_bytes(b: &[u8]) -> Result<Self, serde_json::Error> {
292        Self::deserialize_with_meta(&mut serde_json::Deserializer::from_slice(b))
293    }
294}
295
296impl<T> Annotated<T>
297where
298    T: IntoValue,
299{
300    /// Serializes an annotated value into a serializer.
301    pub fn serialize_with_meta<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
302        let mut map_ser = serializer.serialize_map(None)?;
303        let meta_tree = IntoValue::extract_meta_tree(self);
304
305        if let Some(value) = self.value() {
306            // NOTE: This is a hack and known to be instable use of serde.
307            use serde::__private::ser::FlatMapSerializer;
308            IntoValue::serialize_payload(
309                value,
310                FlatMapSerializer(&mut map_ser),
311                SkipSerialization::default(),
312            )?;
313        }
314
315        if !meta_tree.is_empty() {
316            map_ser.serialize_key("_meta")?;
317            map_ser.serialize_value(&meta_tree)?;
318        }
319        map_ser.end()
320    }
321
322    /// Serializes an annotated value into a JSON string.
323    pub fn to_json(&self) -> Result<String, serde_json::Error> {
324        let mut ser = serde_json::Serializer::new(Vec::with_capacity(128));
325        self.serialize_with_meta(&mut ser)?;
326        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
327    }
328
329    /// Serializes an annotated value into a pretty JSON string.
330    pub fn to_json_pretty(&self) -> Result<String, serde_json::Error> {
331        let mut ser = serde_json::Serializer::pretty(Vec::with_capacity(128));
332        self.serialize_with_meta(&mut ser)?;
333        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
334    }
335
336    /// Serializes an annotated value into a JSON string.
337    pub fn payload_to_json(&self) -> Result<String, serde_json::Error> {
338        let mut ser = serde_json::Serializer::new(Vec::with_capacity(128));
339
340        match self.value() {
341            Some(value) => {
342                IntoValue::serialize_payload(value, &mut ser, SkipSerialization::default())?
343            }
344            None => ser.serialize_unit()?,
345        }
346
347        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
348    }
349
350    /// Serializes an annotated value into a pretty JSON string.
351    pub fn payload_to_json_pretty(&self) -> Result<String, serde_json::Error> {
352        let mut ser = serde_json::Serializer::pretty(Vec::with_capacity(128));
353
354        match self.value() {
355            Some(value) => {
356                IntoValue::serialize_payload(value, &mut ser, SkipSerialization::default())?
357            }
358            None => ser.serialize_unit()?,
359        }
360
361        Ok(unsafe { String::from_utf8_unchecked(ser.into_inner()) })
362    }
363}
364
365impl Annotated<Value> {
366    fn attach_meta_tree(&mut self, mut meta_tree: MetaTree) {
367        match self.value_mut() {
368            Some(Value::Array(items)) => {
369                for (idx, item) in items.iter_mut().enumerate() {
370                    if let Some(meta_tree) = meta_tree.children.remove(&idx.to_string()) {
371                        item.attach_meta_tree(meta_tree);
372                    }
373                }
374            }
375            Some(Value::Object(items)) => {
376                for (key, value) in items.iter_mut() {
377                    if let Some(meta_tree) = meta_tree.children.remove(key) {
378                        value.attach_meta_tree(meta_tree);
379                    }
380                }
381            }
382            _ => {}
383        }
384
385        *self.meta_mut() = meta_tree.meta;
386    }
387}
388
389impl<T> From<T> for Annotated<T> {
390    fn from(t: T) -> Self {
391        Annotated::new(t)
392    }
393}
394
395impl<T> From<Option<T>> for Annotated<T> {
396    fn from(option: Option<T>) -> Self {
397        Annotated(option, Meta::default())
398    }
399}
400
401impl<T> Default for Annotated<T> {
402    fn default() -> Annotated<T> {
403        Annotated::empty()
404    }
405}