Skip to main content

ocapn_syrup/
de.rs

1use std::{fmt::Display, marker::PhantomData};
2
3use num_bigint::Sign;
4use serde::{
5    de::{self, MapAccess, SeqAccess, Visitor},
6    forward_to_deserialize_any, Deserialize,
7};
8
9use crate::format::{value, Error, Result, Value};
10
11impl de::Error for Error {
12    fn custom<T: Display>(msg: T) -> Self {
13        Error::Message(msg.to_string())
14    }
15}
16
17pub struct Deserializer<'de> {
18    input: &'de [u8],
19    pending: Vec<Value>,
20}
21
22impl<'de> Deserializer<'de> {
23    pub fn from_bytes(input: &'de [u8]) -> Self {
24        Deserializer {
25            input,
26            pending: vec![],
27        }
28    }
29
30    fn visit_value<V>(&mut self, visitor: V, value: Value) -> Result<V::Value>
31    where
32        V: Visitor<'de>,
33    {
34        match value {
35            Value::Boolean(v) => visitor.visit_bool(v),
36            Value::Float(v) => visitor.visit_f32(v),
37            Value::Double(v) => visitor.visit_f64(v),
38            Value::Integer(v) => {
39                if v.sign() == Sign::Minus {
40                    visitor.visit_i64(i64::try_from(v).map_err(Error::message)?)
41                } else {
42                    visitor.visit_u64(u64::try_from(v).map_err(Error::message)?)
43                }
44            }
45            Value::Binary(mut v) => {
46                v.reverse();
47                visitor.visit_seq(BinaryDeserializer::new(v))
48            }
49            Value::String(v) => visitor.visit_string(v),
50            Value::Symbol(v) => {
51                if v == "nil" {
52                    visitor.visit_unit()
53                } else {
54                    visitor.visit_string(v)
55                }
56            }
57            Value::Dictionary(mut v) => {
58                v.reverse();
59                visitor.visit_map(DictionaryAccessor::new(self, v))
60            }
61            Value::Sequence(mut v) => {
62                v.reverse();
63                visitor.visit_seq(SequenceAccessor::new(self, v))
64            }
65            Value::Record {
66                label: _,
67                mut fields,
68            } => {
69                if fields.is_empty() {
70                    // Empty fields are either a "nil" unit or a unit struct
71                    return visitor.visit_unit();
72                }
73                if let &Value::Symbol(ref _variant) = &fields[0] {
74                    // Leading symbol indicates an enum variant.
75                    // See Serializer::serialize_*_variant methods.
76                    todo!()
77                } else if fields.len() == 1 {
78                    // A single value is likely some kind of struct (newtype or otherwise).
79                    // Just unwrap it.
80                    self.visit_value(visitor, fields.pop().unwrap())
81                } else {
82                    self.pending.push(Value::Sequence(fields));
83                    visitor.visit_newtype_struct(self)
84                }
85            }
86            Value::Set(mut v) => {
87                v.reverse();
88                visitor.visit_seq(SequenceAccessor::new(self, v))
89            }
90        }
91    }
92}
93
94/// Deserialize a rust value from a byte-slice containing syrup-formatted data.
95pub fn try_from_bytes<'a, T>(b: &'a [u8]) -> Result<T>
96where
97    T: Deserialize<'a>,
98{
99    let mut deserializer = Deserializer::from_bytes(b);
100    let t = T::deserialize(&mut deserializer)?;
101    if deserializer.input.is_empty() {
102        Ok(t)
103    } else {
104        Err(Error::Message("trailing values".to_string()))
105    }
106}
107
108/// Deserialize a rust value from a parsed representation of syrup-formatted data.
109pub fn from_value<'a, T>(v: Value) -> Result<T>
110where
111    T: Deserialize<'a>,
112{
113    let mut deserializer = Deserializer::from_bytes(&[]);
114    deserializer.pending.push(v);
115    let t = T::deserialize(&mut deserializer)?;
116    if deserializer.input.is_empty() {
117        Ok(t)
118    } else {
119        Err(Error::Message("trailing values".to_string()))
120    }
121}
122
123impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
124    type Error = Error;
125
126    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
127    where
128        V: Visitor<'de>,
129    {
130        match self.pending.pop() {
131            Some(next) => self.visit_value(visitor, next),
132            None => {
133                let (remaining, parsed) = value(self.input)?;
134                self.input = remaining;
135                self.visit_value(visitor, parsed)
136            }
137        }
138    }
139
140    forward_to_deserialize_any! {
141        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
142        bytes byte_buf option unit unit_struct newtype_struct seq tuple
143        tuple_struct map struct enum identifier ignored_any
144    }
145}
146
147pub struct BinaryDeserializer<'de> {
148    input: Vec<u8>,
149    _phantom: Option<&'de PhantomData<()>>,
150}
151
152impl<'de> BinaryDeserializer<'de> {
153    fn new(input: Vec<u8>) -> BinaryDeserializer<'de> {
154        BinaryDeserializer {
155            input,
156            _phantom: None,
157        }
158    }
159}
160
161impl<'de, 'a> de::Deserializer<'de> for &'a mut BinaryDeserializer<'de> {
162    type Error = Error;
163
164    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
165    where
166        V: Visitor<'de>,
167    {
168        Err(Error::message("invalid input"))
169    }
170
171    forward_to_deserialize_any! {
172        bool i8 i16 i32 i64 i128 u16 u32 u64 u128 f32 f64 char str string
173        bytes byte_buf option unit unit_struct newtype_struct seq tuple
174        tuple_struct map struct enum identifier ignored_any
175    }
176
177    fn deserialize_u8<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
178    where
179        V: Visitor<'de>,
180    {
181        visitor.visit_u8(self.input.pop().ok_or(Error::message("empty input"))?)
182    }
183}
184
185impl<'de, 'a> SeqAccess<'de> for BinaryDeserializer<'de> {
186    type Error = Error;
187
188    fn next_element_seed<T>(
189        &mut self,
190        seed: T,
191    ) -> std::result::Result<Option<T::Value>, Self::Error>
192    where
193        T: de::DeserializeSeed<'de>,
194    {
195        if self.input.is_empty() {
196            return Ok(None);
197        }
198        seed.deserialize(&mut *self).map(Some)
199    }
200}
201
202struct SequenceAccessor<'a, 'de: 'a> {
203    de: &'a mut Deserializer<'de>,
204    items: Vec<Value>,
205}
206
207impl<'a, 'de> SequenceAccessor<'a, 'de> {
208    fn new(de: &'a mut Deserializer<'de>, items: Vec<Value>) -> Self {
209        SequenceAccessor { de, items }
210    }
211}
212
213impl<'de, 'a> SeqAccess<'de> for SequenceAccessor<'a, 'de> {
214    type Error = Error;
215
216    fn next_element_seed<T>(
217        &mut self,
218        seed: T,
219    ) -> std::result::Result<Option<T::Value>, Self::Error>
220    where
221        T: de::DeserializeSeed<'de>,
222    {
223        match self.items.pop() {
224            None => return Ok(None),
225            Some(next) => {
226                self.de.pending.push(next);
227                seed.deserialize(&mut *self.de).map(Some)
228            }
229        }
230    }
231}
232
233struct DictionaryAccessor<'a, 'de: 'a> {
234    de: &'a mut Deserializer<'de>,
235    items: Vec<(Value, Value)>,
236}
237
238impl<'a, 'de> DictionaryAccessor<'a, 'de> {
239    fn new(de: &'a mut Deserializer<'de>, items: Vec<(Value, Value)>) -> Self {
240        DictionaryAccessor { de, items }
241    }
242}
243
244impl<'de, 'a> MapAccess<'de> for DictionaryAccessor<'a, 'de> {
245    type Error = Error;
246
247    fn next_key_seed<K>(&mut self, seed: K) -> std::result::Result<Option<K::Value>, Self::Error>
248    where
249        K: de::DeserializeSeed<'de>,
250    {
251        match self.items.last() {
252            None => Ok(None),
253            Some(next) => {
254                self.de.pending.push(next.0.clone());
255                seed.deserialize(&mut *self.de).map(Some)
256            }
257        }
258    }
259
260    fn next_value_seed<V>(&mut self, seed: V) -> std::result::Result<V::Value, Self::Error>
261    where
262        V: de::DeserializeSeed<'de>,
263    {
264        match self.items.pop() {
265            None => Err(Error::message("missing expected dictionary entry value")),
266            Some(next) => {
267                self.de.pending.push(next.1);
268                seed.deserialize(&mut *self.de)
269            }
270        }
271    }
272}
273
274#[test]
275fn test_simple_types() {
276    assert_eq!(Ok(true), try_from_bytes::<bool>(br#"t"#.as_slice()));
277    assert_eq!(
278        Ok("foo".as_bytes().to_vec()),
279        try_from_bytes::<Vec<u8>>(br#"3:foo"#.as_slice())
280    );
281    assert_eq!(
282        Ok("foo".to_string()),
283        try_from_bytes::<String>(br#"3"foo"#.as_slice())
284    );
285    assert_eq!(
286        Ok("foo".to_string()),
287        try_from_bytes::<String>(br#"3'foo"#.as_slice())
288    );
289    assert_eq!(
290        Ok(vec![1, 2, 3]),
291        try_from_bytes::<Vec<u64>>(br#"[1+2+3+]"#.as_slice())
292    );
293    assert_eq!(
294        Ok(vec![1, 2, 3]),
295        try_from_bytes::<Vec<u64>>(br#"#1+2+3+$"#.as_slice())
296    );
297    assert_eq!(
298        Ok(vec![vec![1, 2, 3], vec![4, 5, 6]]),
299        try_from_bytes::<Vec<Vec<u64>>>(br#"[[1+2+3+][4+5+6+]]"#.as_slice())
300    );
301}
302
303#[test]
304fn test_from_value() {
305    #[derive(Deserialize, PartialEq, Debug)]
306    struct Test {
307        int: u32,
308        seq: Vec<String>,
309    }
310
311    assert_eq!(
312        Ok(Test {
313            int: 42,
314            seq: vec!["foo".to_owned(), "bar".to_owned()]
315        }),
316        from_value::<Test>(Value::Record {
317            label: Box::new(Value::Symbol("Test".to_owned())),
318            fields: vec![Value::Dictionary(vec![
319                (Value::Symbol("int".to_owned()), Value::Integer(42.into())),
320                (
321                    Value::Symbol("seq".to_owned()),
322                    Value::Sequence(vec![
323                        Value::String("foo".to_owned()),
324                        Value::String("bar".to_owned())
325                    ])
326                )
327            ])]
328        })
329    );
330}
331
332#[test]
333fn test_struct_from_dictionary() {
334    #[derive(Deserialize, PartialEq, Debug)]
335    struct Test {
336        int: u32,
337        seq: Vec<String>,
338    }
339
340    assert_eq!(
341        Ok(Test {
342            int: 42,
343            seq: vec!["foo".to_string(), "bar".to_string()]
344        }),
345        try_from_bytes::<Test>(br#"{3'int42+3'seq[3"foo3"bar]}"#.as_slice())
346    );
347}
348
349#[test]
350fn test_struct_from_record() {
351    #[derive(Deserialize, PartialEq, Debug)]
352    struct Test {
353        int: u32,
354        seq: Vec<String>,
355    }
356
357    assert_eq!(
358        Ok(Test {
359            int: 42,
360            seq: vec!["foo".to_string(), "bar".to_string()]
361        }),
362        try_from_bytes::<Test>(br#"<4'Test{3'int42+3'seq[3"foo3"bar]}>"#.as_slice())
363    );
364
365    // Note that the record label is discarded; the label isn't actually matched or used here.
366    assert_eq!(
367        Ok(Test {
368            int: 42,
369            seq: vec!["foo".to_string(), "bar".to_string()]
370        }),
371        try_from_bytes::<Test>(br#"<5'Other{3'int42+3'seq[3"foo3"bar]}>"#.as_slice())
372    );
373}
374
375#[test]
376fn test_newtype_struct_from_record() {
377    #[derive(Deserialize, PartialEq, Debug)]
378    struct Test((String, i32));
379
380    assert_eq!(
381        Ok(Test(("foo".to_owned(), -42))),
382        try_from_bytes::<Test>(br#"<4'Test3"foo42->"#.as_slice()),
383    );
384}