Skip to main content

one_brackets/
serde_impls.rs

1//! Serde support for the tree types and the helpers [`Rest`], [`Counted`] and [`atom`].
2//!
3//! The bracket format has no field names, only order, so the special types talk to
4//! the crate's serializer and deserializer through reserved newtype and enum names.
5//! Other formats see them as plain newtypes and enums.
6
7use std::fmt;
8use std::marker::PhantomData;
9use std::ops::{Deref, DerefMut};
10
11use serde::de::{self, Deserializer, EnumAccess, VariantAccess, Visitor};
12use serde::ser::{SerializeSeq, Serializer};
13use serde::{Deserialize, Serialize};
14
15use crate::de::take_smuggled_node;
16use crate::error::count_mismatch;
17use crate::{Node, Value};
18
19pub(crate) const NODE: &str = "$one_brackets::Node";
20pub(crate) const VALUE: &str = "$one_brackets::Value";
21pub(crate) const REST: &str = "$one_brackets::Rest";
22pub(crate) const ATOM: &str = "$one_brackets::Atom";
23
24const VARIANTS: &[&str] = &["List", "Str", "Atom"];
25
26/// Remaining items of a list after the preceding fields, kept as is.
27///
28/// Lists map to structs by position, and items past the last field are ignored.
29/// Put a `Rest` as the last field to keep them: it is filled from the rest of the list
30/// and written back in place, so unknown items survive a read-write round trip.
31/// Mark it `#[serde(default)]`: a list may have no extra items at all.
32///
33/// ```
34/// use one_brackets::{Node, Rest};
35/// use serde::{Deserialize, Serialize};
36///
37/// #[derive(Deserialize, Serialize)]
38/// struct Version {
39///     major: u32,
40///     #[serde(default)]
41///     rest: Rest,
42/// }
43///
44/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
45/// let node: Node = "{216,0,{80305,0}}".parse()?;
46/// let version: Version = one_brackets::from_node(&node)?;
47/// assert_eq!(version.major, 216);
48/// assert_eq!(version.rest.len(), 2);
49/// assert_eq!(one_brackets::to_node(&version)?, node);
50/// # Ok(())
51/// # }
52/// ```
53#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
54pub struct Rest(pub Vec<Node>);
55
56impl Deref for Rest {
57    type Target = Vec<Node>;
58
59    fn deref(&self) -> &Vec<Node> {
60        &self.0
61    }
62}
63
64impl DerefMut for Rest {
65    fn deref_mut(&mut self) -> &mut Vec<Node> {
66        &mut self.0
67    }
68}
69
70impl From<Vec<Node>> for Rest {
71    fn from(items: Vec<Node>) -> Self {
72        Rest(items)
73    }
74}
75
76impl Serialize for Rest {
77    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
78        serializer.serialize_newtype_struct(REST, &self.0)
79    }
80}
81
82impl<'de> Deserialize<'de> for Rest {
83    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
84        struct RestVisitor;
85
86        impl<'de> Visitor<'de> for RestVisitor {
87            type Value = Rest;
88
89            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90                f.write_str("remaining list items")
91            }
92
93            fn visit_newtype_struct<D: Deserializer<'de>>(self, d: D) -> Result<Rest, D::Error> {
94                Vec::deserialize(d).map(Rest)
95            }
96
97            fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Rest, A::Error> {
98                let mut items = Vec::new();
99                while let Some(item) = seq.next_element()? {
100                    items.push(item);
101                }
102                Ok(Rest(items))
103            }
104        }
105
106        deserializer.deserialize_newtype_struct(REST, RestVisitor)
107    }
108}
109
110/// A counted list `{count,item1,item2,...}`, the common 1C shape.
111///
112/// The count is checked on reading and written on serialization.
113/// For the [`Node`] API see [`Node::try_counted`] and [`Node::counted`].
114///
115/// ```
116/// use one_brackets::Counted;
117/// use serde::Deserialize;
118///
119/// #[derive(Debug, Deserialize)]
120/// struct Server(String, u16);
121///
122/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
123/// let servers: Counted<Server> = one_brackets::from_str("{2,{\"a\",1541},{\"b\",1541}}")?;
124/// assert_eq!(servers[1].0, "b");
125///
126/// let err = one_brackets::from_str::<Counted<Server>>("{3,{\"a\",1541}}").unwrap_err();
127/// assert_eq!(err.to_string(), "list declares 3 items, but has 1 at line 1, column 1");
128/// # Ok(())
129/// # }
130/// ```
131#[derive(Debug, Clone, PartialEq, Eq, Hash)]
132pub struct Counted<T>(pub Vec<T>);
133
134impl<T> Default for Counted<T> {
135    fn default() -> Self {
136        Counted(Vec::new())
137    }
138}
139
140impl<T> Deref for Counted<T> {
141    type Target = Vec<T>;
142
143    fn deref(&self) -> &Vec<T> {
144        &self.0
145    }
146}
147
148impl<T> DerefMut for Counted<T> {
149    fn deref_mut(&mut self) -> &mut Vec<T> {
150        &mut self.0
151    }
152}
153
154impl<T> From<Vec<T>> for Counted<T> {
155    fn from(items: Vec<T>) -> Self {
156        Counted(items)
157    }
158}
159
160impl<T> FromIterator<T> for Counted<T> {
161    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
162        Counted(iter.into_iter().collect())
163    }
164}
165
166impl<T> IntoIterator for Counted<T> {
167    type Item = T;
168    type IntoIter = std::vec::IntoIter<T>;
169
170    fn into_iter(self) -> Self::IntoIter {
171        self.0.into_iter()
172    }
173}
174
175impl<'a, T> IntoIterator for &'a Counted<T> {
176    type Item = &'a T;
177    type IntoIter = std::slice::Iter<'a, T>;
178
179    fn into_iter(self) -> Self::IntoIter {
180        self.0.iter()
181    }
182}
183
184impl<T: Serialize> Serialize for Counted<T> {
185    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
186        let mut seq = serializer.serialize_seq(Some(self.0.len() + 1))?;
187        seq.serialize_element(&self.0.len())?;
188        for item in &self.0 {
189            seq.serialize_element(item)?;
190        }
191        seq.end()
192    }
193}
194
195impl<'de, T: Deserialize<'de>> Deserialize<'de> for Counted<T> {
196    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
197        struct CountedVisitor<T>(PhantomData<T>);
198
199        impl<'de, T: Deserialize<'de>> Visitor<'de> for CountedVisitor<T> {
200            type Value = Counted<T>;
201
202            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203                f.write_str("a counted list {count,items...}")
204            }
205
206            fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Counted<T>, A::Error> {
207                let declared: usize = seq
208                    .next_element()?
209                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
210                let mut items = Vec::with_capacity(declared.min(4096));
211                while items.len() < declared {
212                    match seq.next_element()? {
213                        Some(item) => items.push(item),
214                        None => return Err(mismatch(declared, items.len())),
215                    }
216                }
217                let mut actual = declared;
218                while seq.next_element::<de::IgnoredAny>()?.is_some() {
219                    actual += 1;
220                }
221                if actual != declared {
222                    return Err(mismatch(declared, actual));
223                }
224                Ok(Counted(items))
225            }
226        }
227
228        fn mismatch<E: de::Error>(declared: usize, actual: usize) -> E {
229            E::custom(count_mismatch(declared, actual))
230        }
231
232        deserializer.deserialize_seq(CountedVisitor(PhantomData))
233    }
234}
235
236/// Field helper for `#[serde(with = "one_brackets::atom")]`.
237///
238/// Strings are written quoted by default. With this helper a field is written
239/// as an unquoted atom (GUID, number, literal) via [`Display`](std::fmt::Display)
240/// and read via [`FromStr`](std::str::FromStr).
241pub mod atom {
242    use std::fmt::Display;
243    use std::str::FromStr;
244
245    use serde::de::Error as _;
246    use serde::{Deserialize, Deserializer, Serializer};
247
248    use crate::node::type_label;
249
250    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
251    where
252        T: Display + ?Sized,
253        S: Serializer,
254    {
255        serializer.serialize_newtype_struct(super::ATOM, &value.to_string())
256    }
257
258    pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
259    where
260        T: FromStr,
261        T::Err: Display,
262        D: Deserializer<'de>,
263    {
264        let text = String::deserialize(deserializer)?;
265        text.parse().map_err(|e| {
266            D::Error::custom(format_args!(
267                "expected {}, found value `{text}` ({e})",
268                type_label::<T>()
269            ))
270        })
271    }
272}
273
274/// Writes an atom: a plain string in other formats.
275struct AtomStr<'a>(&'a str);
276
277impl Serialize for AtomStr<'_> {
278    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
279        serializer.serialize_newtype_struct(ATOM, self.0)
280    }
281}
282
283/// Other formats see `{"List": [...]}`, `{"Str": "..."}` or `{"Atom": "..."}`.
284impl Serialize for Value {
285    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
286        match self {
287            Value::List(items) => serializer.serialize_newtype_variant(VALUE, 0, "List", items),
288            Value::Str(s) => serializer.serialize_newtype_variant(VALUE, 1, "Str", s),
289            Value::Atom(s) => serializer.serialize_newtype_variant(VALUE, 2, "Atom", &AtomStr(s)),
290        }
291    }
292}
293
294impl<'de> Deserialize<'de> for Value {
295    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
296        deserializer.deserialize_enum(VALUE, VARIANTS, ValueVisitor)
297    }
298}
299
300struct ValueVisitor;
301
302impl<'de> Visitor<'de> for ValueVisitor {
303    type Value = Value;
304
305    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
306        f.write_str("a bracket value: List, Str or Atom")
307    }
308
309    fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Value, A::Error> {
310        let (kind, variant) = data.variant()?;
311        match kind {
312            Kind::List => variant.newtype_variant().map(Value::List),
313            Kind::Str => variant.newtype_variant().map(Value::Str),
314            Kind::Atom => variant.newtype_variant().map(Value::Atom),
315        }
316    }
317}
318
319enum Kind {
320    List,
321    Str,
322    Atom,
323}
324
325impl<'de> Deserialize<'de> for Kind {
326    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
327        struct KindVisitor;
328
329        impl Visitor<'_> for KindVisitor {
330            type Value = Kind;
331
332            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333                f.write_str("List, Str or Atom")
334            }
335
336            fn visit_u64<E: de::Error>(self, v: u64) -> Result<Kind, E> {
337                match v {
338                    0 => Ok(Kind::List),
339                    1 => Ok(Kind::Str),
340                    2 => Ok(Kind::Atom),
341                    _ => Err(E::invalid_value(de::Unexpected::Unsigned(v), &self)),
342                }
343            }
344
345            fn visit_str<E: de::Error>(self, v: &str) -> Result<Kind, E> {
346                match v {
347                    "List" => Ok(Kind::List),
348                    "Str" => Ok(Kind::Str),
349                    "Atom" => Ok(Kind::Atom),
350                    _ => Err(E::unknown_variant(v, VARIANTS)),
351                }
352            }
353        }
354
355        deserializer.deserialize_identifier(KindVisitor)
356    }
357}
358
359/// Positions are not written: they belong to the parsed text.
360impl Serialize for Node {
361    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
362        self.value().serialize(serializer)
363    }
364}
365
366/// From this crate's deserializer a node comes out as is, positions included.
367impl<'de> Deserialize<'de> for Node {
368    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
369        struct NodeVisitor;
370
371        impl<'de> Visitor<'de> for NodeVisitor {
372            type Value = Node;
373
374            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375                f.write_str("a bracket node")
376            }
377
378            fn visit_newtype_struct<D: Deserializer<'de>>(self, d: D) -> Result<Node, D::Error> {
379                match take_smuggled_node() {
380                    Some(node) => Ok(node),
381                    None => Value::deserialize(d).map(Node::from),
382                }
383            }
384
385            fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Node, A::Error> {
386                ValueVisitor.visit_enum(data).map(Node::from)
387            }
388        }
389
390        deserializer.deserialize_newtype_struct(NODE, NodeVisitor)
391    }
392}