Skip to main content

one_brackets/
de.rs

1//! Deserialization of a [`Node`] tree into user types.
2//!
3//! Mapping:
4//! - struct, tuple → list, field by position; extra items are ignored (see [`Rest`](crate::Rest));
5//! - `Vec<T>` → list; map → list of `{key,value}` pairs;
6//! - numbers, `bool` (`0`/`1`) → atoms; `String` → string or atom;
7//! - `Option<T>` → `None` for an empty atom;
8//! - enum → atom with the variant index or name, or a list `{variant,data...}`.
9//!
10//! Errors carry the position of the offending node and the path to it.
11
12use std::cell::RefCell;
13use std::io::Read;
14
15use serde::de::{self, DeserializeOwned, DeserializeSeed, IntoDeserializer, Visitor};
16use serde::{Deserialize, forward_to_deserialize_any};
17
18use crate::serde_impls::{NODE, REST, VALUE};
19use crate::{AccessError, Node, Value};
20
21/// Deserializes a user type from a node; `&str` fields can borrow from the node.
22///
23/// ```
24/// use one_brackets::Node;
25/// use serde::{Deserialize, Serialize};
26///
27/// #[derive(Debug, PartialEq, Deserialize, Serialize)]
28/// struct Root {
29///     version: u32,
30///     #[serde(with = "one_brackets::atom")]
31///     object: String,
32///     extra: Option<u32>,
33/// }
34///
35/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
36/// let node: Node = "{2,c2f34349-b1e0-4060-8abf-3c59f38ac69f,}".parse()?;
37/// let root: Root = one_brackets::from_node(&node)?;
38/// assert_eq!(root.version, 2);
39/// assert_eq!(root.extra, None);
40/// assert_eq!(one_brackets::to_string(&root)?, "{2,c2f34349-b1e0-4060-8abf-3c59f38ac69f,}");
41///
42/// let err = one_brackets::from_str::<Root>("{2,\r\n{}}").unwrap_err();
43/// assert_eq!(err.to_string(), "expected string or value, found empty list at line 2, column 1 (path [1])");
44/// # Ok(())
45/// # }
46/// ```
47pub fn from_node<'de, T: Deserialize<'de>>(node: &'de Node) -> Result<T, AccessError> {
48    T::deserialize(NodeDeserializer { node })
49}
50
51/// Parses bracket text and deserializes a user type from it.
52pub fn from_str<T: DeserializeOwned>(text: &str) -> crate::Result<T> {
53    let node: Node = text.parse()?;
54    Ok(from_node(&node)?)
55}
56
57/// Reads bracket text from any [`Read`] and deserializes a user type from it.
58pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> crate::Result<T> {
59    let node = Node::from_reader(reader)?;
60    Ok(from_node(&node)?)
61}
62
63thread_local! {
64    /// Hands a node to `Node::deserialize` as is, positions included:
65    /// the serde data model has no way to carry it.
66    static SMUGGLED: RefCell<Option<Node>> = const { RefCell::new(None) };
67}
68
69pub(crate) fn take_smuggled_node() -> Option<Node> {
70    SMUGGLED.with(|slot| slot.borrow_mut().take())
71}
72
73#[derive(Clone, Copy)]
74struct NodeDeserializer<'de> {
75    node: &'de Node,
76}
77
78impl NodeDeserializer<'_> {
79    /// Points errors raised by visitors at this node.
80    fn locate<T>(&self, result: Result<T, AccessError>) -> Result<T, AccessError> {
81        result.map_err(|e| e.or_position(self.node.position()))
82    }
83}
84
85macro_rules! deserialize_parsed {
86    ($($method:ident => $visit:ident),* $(,)?) => {$(
87        fn $method<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
88            let value = self.node.try_parse()?;
89            self.locate(visitor.$visit(value))
90        }
91    )*};
92}
93
94impl<'de> de::Deserializer<'de> for NodeDeserializer<'de> {
95    type Error = AccessError;
96
97    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
98        let result = match self.node.value() {
99            Value::List(items) => visitor.visit_seq(Seq::new(items)),
100            Value::Atom(s) if s.is_empty() => visitor.visit_unit(),
101            Value::Str(_) | Value::Atom(_) => visitor.visit_borrowed_str(self.node.try_str()?),
102        };
103        self.locate(result)
104    }
105
106    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
107        let value = self.node.try_bool()?;
108        self.locate(visitor.visit_bool(value))
109    }
110
111    deserialize_parsed! {
112        deserialize_i8 => visit_i8,
113        deserialize_i16 => visit_i16,
114        deserialize_i32 => visit_i32,
115        deserialize_i64 => visit_i64,
116        deserialize_i128 => visit_i128,
117        deserialize_u8 => visit_u8,
118        deserialize_u16 => visit_u16,
119        deserialize_u32 => visit_u32,
120        deserialize_u64 => visit_u64,
121        deserialize_u128 => visit_u128,
122        deserialize_f32 => visit_f32,
123        deserialize_f64 => visit_f64,
124    }
125
126    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
127        self.deserialize_str(visitor)
128    }
129
130    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
131        let value = self.node.try_str()?;
132        self.locate(visitor.visit_borrowed_str(value))
133    }
134
135    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
136        self.deserialize_str(visitor)
137    }
138
139    fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
140        let value = self.node.try_str()?;
141        self.locate(visitor.visit_borrowed_bytes(value.as_bytes()))
142    }
143
144    fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
145        self.deserialize_bytes(visitor)
146    }
147
148    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
149        let result = if self.node.is_empty_atom() {
150            visitor.visit_none()
151        } else {
152            visitor.visit_some(self)
153        };
154        self.locate(result)
155    }
156
157    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
158        if !self.node.is_empty_atom() {
159            return Err(self.node.unexpected("empty value"));
160        }
161        self.locate(visitor.visit_unit())
162    }
163
164    fn deserialize_unit_struct<V: Visitor<'de>>(
165        self,
166        _name: &'static str,
167        visitor: V,
168    ) -> Result<V::Value, AccessError> {
169        self.deserialize_unit(visitor)
170    }
171
172    fn deserialize_newtype_struct<V: Visitor<'de>>(
173        self,
174        name: &'static str,
175        visitor: V,
176    ) -> Result<V::Value, AccessError> {
177        if name == NODE {
178            SMUGGLED.with(|slot| *slot.borrow_mut() = Some(self.node.clone()));
179            let result = visitor.visit_newtype_struct(self);
180            take_smuggled_node();
181            return self.locate(result);
182        }
183        self.locate(visitor.visit_newtype_struct(self))
184    }
185
186    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
187        let items = self.node.try_list()?;
188        self.locate(visitor.visit_seq(Seq::new(items)))
189    }
190
191    fn deserialize_tuple<V: Visitor<'de>>(
192        self,
193        len: usize,
194        visitor: V,
195    ) -> Result<V::Value, AccessError> {
196        let items = self.node.try_list()?;
197        self.locate(visitor.visit_seq(Seq::new(items).limit(len)))
198    }
199
200    fn deserialize_tuple_struct<V: Visitor<'de>>(
201        self,
202        _name: &'static str,
203        len: usize,
204        visitor: V,
205    ) -> Result<V::Value, AccessError> {
206        self.deserialize_tuple(len, visitor)
207    }
208
209    fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
210        let items = self.node.try_list()?;
211        self.locate(visitor.visit_map(Map {
212            items,
213            next: 0,
214            value: None,
215        }))
216    }
217
218    fn deserialize_struct<V: Visitor<'de>>(
219        self,
220        _name: &'static str,
221        fields: &'static [&'static str],
222        visitor: V,
223    ) -> Result<V::Value, AccessError> {
224        self.deserialize_tuple(fields.len(), visitor)
225    }
226
227    fn deserialize_enum<V: Visitor<'de>>(
228        self,
229        name: &'static str,
230        _variants: &'static [&'static str],
231        visitor: V,
232    ) -> Result<V::Value, AccessError> {
233        if name == VALUE {
234            return self.locate(visitor.visit_enum(ValueAccess(self.node)));
235        }
236        let variant = match self.node.value() {
237            Value::List(items) => {
238                let (tag, data) = items
239                    .split_first()
240                    .ok_or_else(|| self.node.unexpected("enum variant"))?;
241                Variant {
242                    tag,
243                    data,
244                    in_list: true,
245                }
246            }
247            _ => Variant {
248                tag: self.node,
249                data: &[],
250                in_list: false,
251            },
252        };
253        self.locate(visitor.visit_enum(variant))
254    }
255
256    /// Numeric atoms select a variant or a field by index, others by name.
257    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
258        match self.node.as_atom() {
259            Some(s) if !s.is_empty() && s.bytes().all(|b| b.is_ascii_digit()) => {
260                let index = self.node.try_parse()?;
261                self.locate(visitor.visit_u64(index))
262            }
263            _ => self.deserialize_str(visitor),
264        }
265    }
266
267    fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
268        self.locate(visitor.visit_unit())
269    }
270}
271
272/// List items in order. `end` limits a struct or tuple to its own fields.
273struct Seq<'de> {
274    items: &'de [Node],
275    next: usize,
276    end: usize,
277    /// Index of `items[0]` in the parent list, for error paths.
278    offset: usize,
279    /// Item taken by the current element; `None` when a [`Rest`](crate::Rest) took the rest.
280    taken: Option<usize>,
281}
282
283impl<'de> Seq<'de> {
284    fn new(items: &'de [Node]) -> Self {
285        Seq {
286            items,
287            next: 0,
288            end: items.len(),
289            offset: 0,
290            taken: None,
291        }
292    }
293
294    fn limit(mut self, len: usize) -> Self {
295        self.end = self.end.min(len);
296        self
297    }
298
299    fn offset(mut self, offset: usize) -> Self {
300        self.offset = offset;
301        self
302    }
303}
304
305impl<'de> de::SeqAccess<'de> for Seq<'de> {
306    type Error = AccessError;
307
308    fn next_element_seed<T: DeserializeSeed<'de>>(
309        &mut self,
310        seed: T,
311    ) -> Result<Option<T::Value>, AccessError> {
312        if self.next >= self.end {
313            return Ok(None);
314        }
315        self.taken = None;
316        seed.deserialize(Element { seq: self })
317            .map(Some)
318            .map_err(|e| match self.taken {
319                Some(i) => e
320                    .or_position(self.items[i].position())
321                    .prepend_path(self.offset + i),
322                None => e,
323            })
324    }
325
326    fn size_hint(&self) -> Option<usize> {
327        Some(self.end.saturating_sub(self.next))
328    }
329}
330
331/// The next list item; takes it only when its type is known, so a `Rest` can take the rest.
332struct Element<'a, 'de> {
333    seq: &'a mut Seq<'de>,
334}
335
336impl<'de> Element<'_, 'de> {
337    fn take(self) -> NodeDeserializer<'de> {
338        let items = self.seq.items;
339        let index = self.seq.next;
340        self.seq.next += 1;
341        self.seq.taken = Some(index);
342        NodeDeserializer {
343            node: &items[index],
344        }
345    }
346}
347
348macro_rules! forward_to_node {
349    ($($method:ident($($arg:ident: $ty:ty),*)),* $(,)?) => {$(
350        fn $method<V: Visitor<'de>>(self, $($arg: $ty,)* visitor: V) -> Result<V::Value, AccessError> {
351            self.take().$method($($arg,)* visitor)
352        }
353    )*};
354}
355
356impl<'de> de::Deserializer<'de> for Element<'_, 'de> {
357    type Error = AccessError;
358
359    forward_to_node! {
360        deserialize_any(),
361        deserialize_bool(),
362        deserialize_i8(),
363        deserialize_i16(),
364        deserialize_i32(),
365        deserialize_i64(),
366        deserialize_i128(),
367        deserialize_u8(),
368        deserialize_u16(),
369        deserialize_u32(),
370        deserialize_u64(),
371        deserialize_u128(),
372        deserialize_f32(),
373        deserialize_f64(),
374        deserialize_char(),
375        deserialize_str(),
376        deserialize_string(),
377        deserialize_bytes(),
378        deserialize_byte_buf(),
379        deserialize_option(),
380        deserialize_unit(),
381        deserialize_unit_struct(name: &'static str),
382        deserialize_seq(),
383        deserialize_tuple(len: usize),
384        deserialize_tuple_struct(name: &'static str, len: usize),
385        deserialize_map(),
386        deserialize_struct(name: &'static str, fields: &'static [&'static str]),
387        deserialize_enum(name: &'static str, variants: &'static [&'static str]),
388        deserialize_identifier(),
389        deserialize_ignored_any(),
390    }
391
392    fn deserialize_newtype_struct<V: Visitor<'de>>(
393        self,
394        name: &'static str,
395        visitor: V,
396    ) -> Result<V::Value, AccessError> {
397        if name != REST {
398            return self.take().deserialize_newtype_struct(name, visitor);
399        }
400        let seq = self.seq;
401        let start = seq.next;
402        let rest = &seq.items[start..];
403        seq.next = seq.items.len();
404        visitor.visit_newtype_struct(RestDeserializer(Seq::new(rest).offset(seq.offset + start)))
405    }
406}
407
408/// The rest of a list, as a sequence.
409struct RestDeserializer<'de>(Seq<'de>);
410
411impl<'de> de::Deserializer<'de> for RestDeserializer<'de> {
412    type Error = AccessError;
413
414    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, AccessError> {
415        visitor.visit_seq(self.0)
416    }
417
418    forward_to_deserialize_any! {
419        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
420        bytes byte_buf option unit unit_struct newtype_struct seq tuple
421        tuple_struct map struct enum identifier ignored_any
422    }
423}
424
425/// A list of `{key,value}` pairs.
426struct Map<'de> {
427    items: &'de [Node],
428    next: usize,
429    value: Option<&'de Node>,
430}
431
432impl<'de> de::MapAccess<'de> for Map<'de> {
433    type Error = AccessError;
434
435    fn next_key_seed<K: DeserializeSeed<'de>>(
436        &mut self,
437        seed: K,
438    ) -> Result<Option<K::Value>, AccessError> {
439        let Some(entry) = self.items.get(self.next) else {
440            return Ok(None);
441        };
442        let index = self.next;
443        self.next += 1;
444        let locate = |e: AccessError| e.or_position(entry.position()).prepend_path(index);
445        let key = entry.try_get(0).map_err(locate)?;
446        self.value = Some(entry.try_get(1).map_err(locate)?);
447        seed.deserialize(NodeDeserializer { node: key })
448            .map(Some)
449            .map_err(|e| locate(e.or_position(key.position()).prepend_path(0)))
450    }
451
452    fn next_value_seed<V: DeserializeSeed<'de>>(
453        &mut self,
454        seed: V,
455    ) -> Result<V::Value, AccessError> {
456        let value = self
457            .value
458            .take()
459            .ok_or_else(|| de::Error::custom("map value requested before its key"))?;
460        let index = self.next - 1;
461        seed.deserialize(NodeDeserializer { node: value })
462            .map_err(|e| {
463                e.or_position(value.position())
464                    .prepend_path(1)
465                    .prepend_path(index)
466            })
467    }
468
469    fn size_hint(&self) -> Option<usize> {
470        Some(self.items.len() - self.next)
471    }
472}
473
474/// A user enum: an atom with the variant, or a list `{variant,data...}`.
475struct Variant<'de> {
476    tag: &'de Node,
477    data: &'de [Node],
478    in_list: bool,
479}
480
481impl<'de> de::EnumAccess<'de> for Variant<'de> {
482    type Error = AccessError;
483    type Variant = Self;
484
485    fn variant_seed<V: DeserializeSeed<'de>>(
486        self,
487        seed: V,
488    ) -> Result<(V::Value, Self), AccessError> {
489        let value = seed
490            .deserialize(NodeDeserializer { node: self.tag })
491            .map_err(|e| {
492                let e = e.or_position(self.tag.position());
493                if self.in_list { e.prepend_path(0) } else { e }
494            })?;
495        Ok((value, self))
496    }
497}
498
499impl<'de> de::VariantAccess<'de> for Variant<'de> {
500    type Error = AccessError;
501
502    fn unit_variant(self) -> Result<(), AccessError> {
503        Ok(())
504    }
505
506    fn newtype_variant_seed<T: DeserializeSeed<'de>>(
507        self,
508        seed: T,
509    ) -> Result<T::Value, AccessError> {
510        let node = self.data.first().ok_or_else(|| {
511            de::Error::custom("expected a list {variant,value} for a variant with data")
512        })?;
513        seed.deserialize(NodeDeserializer { node })
514            .map_err(|e| e.or_position(node.position()).prepend_path(1))
515    }
516
517    fn tuple_variant<V: Visitor<'de>>(
518        self,
519        len: usize,
520        visitor: V,
521    ) -> Result<V::Value, AccessError> {
522        visitor.visit_seq(Seq::new(self.data).limit(len).offset(1))
523    }
524
525    fn struct_variant<V: Visitor<'de>>(
526        self,
527        fields: &'static [&'static str],
528        visitor: V,
529    ) -> Result<V::Value, AccessError> {
530        self.tuple_variant(fields.len(), visitor)
531    }
532}
533
534/// [`Value`] itself: the variant follows the node kind.
535struct ValueAccess<'de>(&'de Node);
536
537impl<'de> de::EnumAccess<'de> for ValueAccess<'de> {
538    type Error = AccessError;
539    type Variant = Self;
540
541    fn variant_seed<V: DeserializeSeed<'de>>(
542        self,
543        seed: V,
544    ) -> Result<(V::Value, Self), AccessError> {
545        let index: u32 = match self.0.value() {
546            Value::List(_) => 0,
547            Value::Str(_) => 1,
548            Value::Atom(_) => 2,
549        };
550        let value = seed.deserialize(IntoDeserializer::<AccessError>::into_deserializer(index))?;
551        Ok((value, self))
552    }
553}
554
555impl<'de> de::VariantAccess<'de> for ValueAccess<'de> {
556    type Error = AccessError;
557
558    fn unit_variant(self) -> Result<(), AccessError> {
559        Err(de::Error::custom("bracket values are newtype variants"))
560    }
561
562    fn newtype_variant_seed<T: DeserializeSeed<'de>>(
563        self,
564        seed: T,
565    ) -> Result<T::Value, AccessError> {
566        seed.deserialize(NodeDeserializer { node: self.0 })
567    }
568
569    fn tuple_variant<V: Visitor<'de>>(
570        self,
571        _len: usize,
572        _visitor: V,
573    ) -> Result<V::Value, AccessError> {
574        Err(de::Error::custom("bracket values are newtype variants"))
575    }
576
577    fn struct_variant<V: Visitor<'de>>(
578        self,
579        _fields: &'static [&'static str],
580        _visitor: V,
581    ) -> Result<V::Value, AccessError> {
582        Err(de::Error::custom("bracket values are newtype variants"))
583    }
584}