ryan/
de.rs

1use std::borrow::Cow;
2use std::fmt::Display;
3
4use serde::de::value::{MapAccessDeserializer, MapDeserializer, SeqDeserializer, StrDeserializer};
5use serde::de::{IntoDeserializer, Visitor};
6use serde::Deserializer;
7
8use crate::parser::{Type, Value};
9
10#[derive(Debug, Clone, Copy)]
11pub enum MaterializedType {
12    Unit,
13    Bool,
14    I8,
15    I16,
16    I32,
17    I64,
18    U8,
19    U16,
20    U32,
21    U64,
22    F32,
23    F64,
24    Char,
25    String,
26    Bytes,
27    List,
28    Map,
29    Enum,
30}
31
32impl Display for MaterializedType {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        let name = match self {
35            MaterializedType::Unit => "null",
36            MaterializedType::Bool => "a boolean",
37            MaterializedType::I8 => "an 8-bit signed integer",
38            MaterializedType::I16 => "a 16-bit signed integer",
39            MaterializedType::I32 => "a 32-bit signed integer",
40            MaterializedType::I64 => "a 64-bit signed integer",
41            MaterializedType::U8 => "an 8-bit positive integer",
42            MaterializedType::U16 => "a 16-bit positive integer",
43            MaterializedType::U32 => "a 32-bit positive integer",
44            MaterializedType::U64 => "a 64-bit positive integer",
45            MaterializedType::F32 => "a single precision float",
46            MaterializedType::F64 => "a double precision float",
47            MaterializedType::Char => "a single character",
48            MaterializedType::String => "text",
49            MaterializedType::Bytes => "a list of 8-bit unsigned integers",
50            MaterializedType::List => "a list of values",
51            MaterializedType::Map => "a key-value map",
52            MaterializedType::Enum => "an enumeration",
53        };
54
55        write!(f, "{name}")
56    }
57}
58
59#[derive(Debug, thiserror::Error)]
60pub enum DecodeError {
61    #[error("{0}")]
62    Message(String),
63    #[error("Cannot dynamically deserialize value of type {typ}")]
64    DeserializeAnyError { typ: Type },
65    #[error("expected {expected} but got value of type {got}")]
66    TypeError {
67        expected: MaterializedType,
68        got: Type,
69    },
70    #[error("cannot fit the number {got} into {expected}")]
71    RangeError {
72        expected: MaterializedType,
73        got: i64,
74    },
75    #[error("expected list of length {expected} but got list of length {got}")]
76    LengthMismatch { expected: usize, got: usize },
77}
78
79impl serde::de::Error for DecodeError {
80    fn custom<T: Display>(msg: T) -> Self {
81        DecodeError::Message(msg.to_string())
82    }
83}
84
85pub struct RyanDeserializer<'de> {
86    pub(crate) value: Cow<'de, Value>,
87}
88
89impl<'de> IntoDeserializer<'de, DecodeError> for RyanDeserializer<'de> {
90    type Deserializer = Self;
91    fn into_deserializer(self) -> Self::Deserializer {
92        self
93    }
94}
95
96impl<'de> Deserializer<'de> for RyanDeserializer<'de> {
97    type Error = DecodeError;
98
99    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
100    where
101        V: Visitor<'de>,
102    {
103        match &*self.value {
104            Value::Null => self.deserialize_unit(visitor),
105            Value::Bool(_) => self.deserialize_bool(visitor),
106            Value::Integer(_) => self.deserialize_i64(visitor),
107            Value::Float(_) => self.deserialize_f64(visitor),
108            Value::Text(_) => self.deserialize_str(visitor),
109            Value::List(_) => self.deserialize_seq(visitor),
110            Value::Map(_) => self.deserialize_map(visitor),
111            v => Err(DecodeError::DeserializeAnyError {
112                typ: v.canonical_type(),
113            }),
114        }
115    }
116
117    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
118    where
119        V: Visitor<'de>,
120    {
121        match &*self.value {
122            &Value::Bool(b) => visitor.visit_bool(b),
123            v => Err(DecodeError::TypeError {
124                expected: MaterializedType::Bool,
125                got: v.canonical_type(),
126            }),
127        }
128    }
129
130    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
131    where
132        V: Visitor<'de>,
133    {
134        match &*self.value {
135            &Value::Integer(int) if int as i8 as i64 == int => visitor.visit_i8(int as i8),
136            &Value::Integer(int) => Err(DecodeError::RangeError {
137                expected: MaterializedType::I8,
138                got: int,
139            }),
140            v => Err(DecodeError::TypeError {
141                expected: MaterializedType::I8,
142                got: v.canonical_type(),
143            }),
144        }
145    }
146
147    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
148    where
149        V: Visitor<'de>,
150    {
151        match &*self.value {
152            &Value::Integer(int) if int as i16 as i64 == int => visitor.visit_i16(int as i16),
153            &Value::Integer(int) => Err(DecodeError::RangeError {
154                expected: MaterializedType::I16,
155                got: int,
156            }),
157            v => Err(DecodeError::TypeError {
158                expected: MaterializedType::I16,
159                got: v.canonical_type(),
160            }),
161        }
162    }
163
164    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
165    where
166        V: Visitor<'de>,
167    {
168        match &*self.value {
169            &Value::Integer(int) if int as i32 as i64 == int => visitor.visit_i32(int as i32),
170            &Value::Integer(int) => Err(DecodeError::RangeError {
171                expected: MaterializedType::I32,
172                got: int,
173            }),
174            v => Err(DecodeError::TypeError {
175                expected: MaterializedType::I32,
176                got: v.canonical_type(),
177            }),
178        }
179    }
180
181    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
182    where
183        V: Visitor<'de>,
184    {
185        match &*self.value {
186            &Value::Integer(int) => visitor.visit_i64(int),
187            v => Err(DecodeError::TypeError {
188                expected: MaterializedType::I64,
189                got: v.canonical_type(),
190            }),
191        }
192    }
193
194    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
195    where
196        V: Visitor<'de>,
197    {
198        match &*self.value {
199            &Value::Integer(int) if int as u8 as i64 == int => visitor.visit_u8(int as u8),
200            &Value::Integer(int) => Err(DecodeError::RangeError {
201                expected: MaterializedType::U8,
202                got: int,
203            }),
204            v => Err(DecodeError::TypeError {
205                expected: MaterializedType::U8,
206                got: v.canonical_type(),
207            }),
208        }
209    }
210
211    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
212    where
213        V: Visitor<'de>,
214    {
215        match &*self.value {
216            &Value::Integer(int) if int as u16 as i64 == int => visitor.visit_u16(int as u16),
217            &Value::Integer(int) => Err(DecodeError::RangeError {
218                expected: MaterializedType::U16,
219                got: int,
220            }),
221            v => Err(DecodeError::TypeError {
222                expected: MaterializedType::U16,
223                got: v.canonical_type(),
224            }),
225        }
226    }
227
228    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
229    where
230        V: Visitor<'de>,
231    {
232        match &*self.value {
233            &Value::Integer(int) if int as u32 as i64 == int => visitor.visit_u32(int as u32),
234            &Value::Integer(int) => Err(DecodeError::RangeError {
235                expected: MaterializedType::U32,
236                got: int,
237            }),
238            v => Err(DecodeError::TypeError {
239                expected: MaterializedType::U32,
240                got: v.canonical_type(),
241            }),
242        }
243    }
244
245    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
246    where
247        V: Visitor<'de>,
248    {
249        match &*self.value {
250            &Value::Integer(int) if int as u64 as i64 == int => visitor.visit_u64(int as u64),
251            &Value::Integer(int) => Err(DecodeError::RangeError {
252                expected: MaterializedType::U64,
253                got: int,
254            }),
255            v => Err(DecodeError::TypeError {
256                expected: MaterializedType::U64,
257                got: v.canonical_type(),
258            }),
259        }
260    }
261
262    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
263    where
264        V: Visitor<'de>,
265    {
266        match &*self.value {
267            &Value::Integer(int) if int as f32 as i64 == int => visitor.visit_f32(int as f32),
268            &Value::Integer(int) => Err(DecodeError::RangeError {
269                expected: MaterializedType::F32,
270                got: int,
271            }),
272            &Value::Float(float) => visitor.visit_f32(float as f32),
273            v => Err(DecodeError::TypeError {
274                expected: MaterializedType::F32,
275                got: v.canonical_type(),
276            }),
277        }
278    }
279
280    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
281    where
282        V: Visitor<'de>,
283    {
284        match &*self.value {
285            &Value::Integer(int) if int as f64 as i64 == int => visitor.visit_f64(int as f64),
286            &Value::Integer(int) => Err(DecodeError::RangeError {
287                expected: MaterializedType::F64,
288                got: int,
289            }),
290            &Value::Float(float) => visitor.visit_f64(float),
291            v => Err(DecodeError::TypeError {
292                expected: MaterializedType::F64,
293                got: v.canonical_type(),
294            }),
295        }
296    }
297
298    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
299    where
300        V: Visitor<'de>,
301    {
302        match &*self.value {
303            Value::Text(s) if s.len() == 1 => {
304                visitor.visit_char(s.chars().next().expect("non-empty strings"))
305            }
306            v => Err(DecodeError::TypeError {
307                expected: MaterializedType::Char,
308                got: v.canonical_type(),
309            }),
310        }
311    }
312
313    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
314    where
315        V: Visitor<'de>,
316    {
317        match &*self.value {
318            Value::Text(s) => visitor.visit_str(s),
319            v => Err(DecodeError::TypeError {
320                expected: MaterializedType::String,
321                got: v.canonical_type(),
322            }),
323        }
324    }
325
326    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
327    where
328        V: Visitor<'de>,
329    {
330        self.deserialize_str(visitor)
331    }
332
333    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
334    where
335        V: Visitor<'de>,
336    {
337        match &*self.value {
338            Value::List(list) => {
339                let bytes = list
340                    .iter()
341                    .map(|item| match item {
342                        &Value::Integer(int) if int as u8 as i64 == int => Ok(int as u8),
343                        &Value::Integer(int) => Err(DecodeError::RangeError {
344                            expected: MaterializedType::U8,
345                            got: int,
346                        }),
347                        v => Err(DecodeError::TypeError {
348                            expected: MaterializedType::U8,
349                            got: v.canonical_type(),
350                        }),
351                    })
352                    .collect::<Result<Vec<_>, _>>()?;
353
354                visitor.visit_byte_buf(bytes)
355            }
356            v => Err(DecodeError::TypeError {
357                expected: MaterializedType::Bytes,
358                got: v.canonical_type(),
359            }),
360        }
361    }
362
363    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
364    where
365        V: Visitor<'de>,
366    {
367        self.deserialize_bytes(visitor)
368    }
369
370    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
371    where
372        V: Visitor<'de>,
373    {
374        match &*self.value {
375            Value::Null => visitor.visit_none(),
376            _ => visitor.visit_some(Self { value: self.value }),
377        }
378    }
379
380    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
381    where
382        V: Visitor<'de>,
383    {
384        match &*self.value {
385            Value::Null => visitor.visit_unit(),
386            v => Err(DecodeError::TypeError {
387                expected: MaterializedType::Unit,
388                got: v.canonical_type(),
389            }),
390        }
391    }
392
393    fn deserialize_unit_struct<V>(
394        self,
395        _name: &'static str,
396        visitor: V,
397    ) -> Result<V::Value, Self::Error>
398    where
399        V: Visitor<'de>,
400    {
401        self.deserialize_unit(visitor)
402    }
403
404    fn deserialize_newtype_struct<V>(
405        self,
406        _name: &'static str,
407        visitor: V,
408    ) -> Result<V::Value, Self::Error>
409    where
410        V: Visitor<'de>,
411    {
412        visitor.visit_newtype_struct(self)
413    }
414
415    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
416    where
417        V: Visitor<'de>,
418    {
419        match &*self.value {
420            Value::List(list) => {
421                let values = list.iter().map(|item| Self {
422                    value: Cow::Owned(item.clone()),
423                });
424                visitor.visit_seq(SeqDeserializer::new(values))
425            }
426            v => Err(DecodeError::TypeError {
427                expected: MaterializedType::List,
428                got: v.canonical_type(),
429            }),
430        }
431    }
432
433    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
434    where
435        V: Visitor<'de>,
436    {
437        match &*self.value {
438            Value::List(list) if list.len() == len => self.deserialize_seq(visitor),
439            Value::List(list) => Err(DecodeError::LengthMismatch {
440                expected: len,
441                got: list.len(),
442            }),
443            v => Err(DecodeError::TypeError {
444                expected: MaterializedType::List,
445                got: v.canonical_type(),
446            }),
447        }
448    }
449
450    fn deserialize_tuple_struct<V>(
451        self,
452        _name: &'static str,
453        len: usize,
454        visitor: V,
455    ) -> Result<V::Value, Self::Error>
456    where
457        V: Visitor<'de>,
458    {
459        self.deserialize_tuple(len, visitor)
460    }
461
462    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
463    where
464        V: Visitor<'de>,
465    {
466        match &*self.value {
467            Value::Map(dict) => {
468                let values = dict.iter().map(|(key, item)| {
469                    (
470                        Self {
471                            value: Cow::Owned(Value::Text(key.clone())),
472                        },
473                        Self {
474                            value: Cow::Owned(item.clone()),
475                        },
476                    )
477                });
478                visitor.visit_map(MapDeserializer::new(values))
479            }
480            v => Err(DecodeError::TypeError {
481                expected: MaterializedType::Map,
482                got: v.canonical_type(),
483            }),
484        }
485    }
486
487    fn deserialize_struct<V>(
488        self,
489        _name: &'static str,
490        _fields: &'static [&'static str],
491        visitor: V,
492    ) -> Result<V::Value, Self::Error>
493    where
494        V: Visitor<'de>,
495    {
496        self.deserialize_map(visitor)
497    }
498
499    fn deserialize_enum<V>(
500        self,
501        _name: &'static str,
502        _variants: &'static [&'static str],
503        visitor: V,
504    ) -> Result<V::Value, Self::Error>
505    where
506        V: Visitor<'de>,
507    {
508        match &*self.value {
509            Value::Text(string) => visitor.visit_enum(StrDeserializer::new(string)),
510            Value::Map(dict) => {
511                let values = dict.iter().map(|(key, item)| {
512                    (
513                        Self {
514                            value: Cow::Owned(Value::Text(key.clone())),
515                        },
516                        Self {
517                            value: Cow::Owned(item.clone()),
518                        },
519                    )
520                });
521                visitor.visit_enum(MapAccessDeserializer::new(MapDeserializer::new(values)))
522            }
523            v => Err(DecodeError::TypeError {
524                expected: MaterializedType::Enum,
525                got: v.canonical_type(),
526            }),
527        }
528    }
529
530    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
531    where
532        V: Visitor<'de>,
533    {
534        self.deserialize_str(visitor)
535    }
536
537    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
538    where
539        V: Visitor<'de>,
540    {
541        self.deserialize_any(visitor)
542    }
543}