serde_intermediate/de/
intermediate.rs

1use crate::{error::*, value::intermediate::*};
2use serde::{
3    de::{
4        DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor,
5    },
6    forward_to_deserialize_any, Deserialize,
7};
8
9#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
10pub enum DeserializeMode {
11    Exact,
12    #[default]
13    Interpret,
14}
15
16pub fn deserialize<'a, T>(value: &'a Intermediate) -> Result<T>
17where
18    T: Deserialize<'a>,
19{
20    T::deserialize(Deserializer::from_intermediate(value, Default::default()))
21}
22
23pub fn deserialize_as<'a, T>(value: &'a Intermediate, mode: DeserializeMode) -> Result<T>
24where
25    T: Deserialize<'a>,
26{
27    T::deserialize(Deserializer::from_intermediate(value, mode))
28}
29
30#[derive(Debug)]
31pub struct Deserializer<'de> {
32    input: &'de Intermediate,
33    mode: DeserializeMode,
34}
35
36impl<'de> Deserializer<'de> {
37    pub fn from_intermediate(input: &'de Intermediate, mode: DeserializeMode) -> Self {
38        Self { input, mode }
39    }
40}
41
42impl<'de> serde::de::Deserializer<'de> for Deserializer<'de> {
43    type Error = Error;
44
45    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
46    where
47        V: Visitor<'de>,
48    {
49        match self.input {
50            Intermediate::Unit => visitor.visit_unit(),
51            Intermediate::Bool(v) => visitor.visit_bool(*v),
52            Intermediate::I8(v) => visitor.visit_i8(*v),
53            Intermediate::I16(v) => visitor.visit_i16(*v),
54            Intermediate::I32(v) => visitor.visit_i32(*v),
55            Intermediate::I64(v) => visitor.visit_i64(*v),
56            Intermediate::I128(v) => visitor.visit_i128(*v),
57            Intermediate::U8(v) => visitor.visit_u8(*v),
58            Intermediate::U16(v) => visitor.visit_u16(*v),
59            Intermediate::U32(v) => visitor.visit_u32(*v),
60            Intermediate::U64(v) => visitor.visit_u64(*v),
61            Intermediate::U128(v) => visitor.visit_u128(*v),
62            Intermediate::F32(v) => visitor.visit_f32(*v),
63            Intermediate::F64(v) => visitor.visit_f64(*v),
64            Intermediate::Char(v) => visitor.visit_char(*v),
65            Intermediate::String(v) => visitor.visit_borrowed_str(v),
66            Intermediate::Bytes(v) => visitor.visit_bytes(v),
67            Intermediate::Option(v) => match v {
68                Some(v) => visitor.visit_some(Self::from_intermediate(v, self.mode)),
69                None => visitor.visit_none(),
70            },
71            Intermediate::UnitStruct => visitor.visit_unit(),
72            Intermediate::UnitVariant(n) => visitor.visit_enum(EnumDeserializer::Unit { name: n }),
73            Intermediate::NewTypeStruct(v) => {
74                visitor.visit_newtype_struct(Self::from_intermediate(v, self.mode))
75            }
76            Intermediate::NewTypeVariant(n, v) => visitor.visit_enum(EnumDeserializer::NewType {
77                name: n,
78                content: v,
79                mode: self.mode,
80            }),
81            Intermediate::Seq(v) | Intermediate::Tuple(v) | Intermediate::TupleStruct(v) => visitor
82                .visit_seq(SeqDeserializer {
83                    values: v.as_slice(),
84                    index: 0,
85                    mode: self.mode,
86                }),
87            Intermediate::TupleVariant(n, v) => visitor.visit_enum(EnumDeserializer::Tuple {
88                name: n,
89                content: v,
90                mode: self.mode,
91            }),
92            Intermediate::Map(v) => visitor.visit_map(MapDeserializer {
93                values: v.as_slice(),
94                index: 0,
95                mode: self.mode,
96            }),
97            Intermediate::Struct(v) => visitor.visit_map(StructDeserializer {
98                values: v.as_slice(),
99                index: 0,
100                mode: self.mode,
101            }),
102            Intermediate::StructVariant(n, v) => visitor.visit_enum(EnumDeserializer::Struct {
103                name: n,
104                content: EnumDeserializerStructContent::Fields(v),
105                mode: self.mode,
106            }),
107        }
108    }
109
110    fn deserialize_newtype_struct<V>(self, _: &'static str, visitor: V) -> Result<V::Value>
111    where
112        V: Visitor<'de>,
113    {
114        if self.mode == DeserializeMode::Interpret {
115            match self.input {
116                Intermediate::Option(v) => {
117                    if let Some(v) = v {
118                        return visitor.visit_newtype_struct(Self::from_intermediate(v, self.mode));
119                    }
120                }
121                Intermediate::NewTypeStruct(v) | Intermediate::NewTypeVariant(_, v) => {
122                    return visitor.visit_newtype_struct(Self::from_intermediate(v, self.mode));
123                }
124                Intermediate::Seq(v)
125                | Intermediate::Tuple(v)
126                | Intermediate::TupleStruct(v)
127                | Intermediate::TupleVariant(_, v) => {
128                    if v.len() == 1 {
129                        return visitor.visit_newtype_struct(Self::from_intermediate(
130                            v.first().unwrap(),
131                            self.mode,
132                        ));
133                    }
134                }
135                Intermediate::Map(v) => {
136                    if v.len() == 1 {
137                        return visitor.visit_newtype_struct(Self::from_intermediate(
138                            &v.first().unwrap().1,
139                            self.mode,
140                        ));
141                    }
142                }
143                Intermediate::Struct(v) | Intermediate::StructVariant(_, v) => {
144                    if v.len() == 1 {
145                        return visitor.visit_newtype_struct(Self::from_intermediate(
146                            &v.first().unwrap().1,
147                            self.mode,
148                        ));
149                    }
150                }
151                _ => return visitor.visit_newtype_struct(self),
152            }
153        }
154        self.deserialize_any(visitor)
155    }
156
157    fn deserialize_enum<V>(
158        self,
159        _: &'static str,
160        variants: &'static [&'static str],
161        visitor: V,
162    ) -> Result<V::Value>
163    where
164        V: Visitor<'de>,
165    {
166        if self.mode == DeserializeMode::Interpret {
167            match self.input {
168                Intermediate::String(v) => {
169                    return visitor.visit_enum(EnumDeserializer::Unit { name: v })
170                }
171                Intermediate::Map(v) => {
172                    if v.len() == 1 {
173                        let (k, v) = v.first().unwrap();
174                        if let Intermediate::String(k) = k {
175                            if variants.contains(&k.as_str()) {
176                                match v {
177                                    Intermediate::Seq(v)
178                                    | Intermediate::Tuple(v)
179                                    | Intermediate::TupleStruct(v) => {
180                                        return visitor.visit_enum(EnumDeserializer::Tuple {
181                                            name: k,
182                                            content: v,
183                                            mode: self.mode,
184                                        })
185                                    }
186                                    Intermediate::Map(v) => {
187                                        return visitor.visit_enum(EnumDeserializer::Struct {
188                                            name: k,
189                                            content: EnumDeserializerStructContent::Entries(v),
190                                            mode: self.mode,
191                                        })
192                                    }
193                                    Intermediate::Struct(v) => {
194                                        return visitor.visit_enum(EnumDeserializer::Struct {
195                                            name: k,
196                                            content: EnumDeserializerStructContent::Fields(v),
197                                            mode: self.mode,
198                                        })
199                                    }
200                                    _ => {
201                                        return visitor.visit_enum(EnumDeserializer::NewType {
202                                            name: k,
203                                            content: v,
204                                            mode: self.mode,
205                                        })
206                                    }
207                                }
208                            }
209                        }
210                    }
211                }
212                Intermediate::Struct(v) => {
213                    if v.len() == 1 {
214                        let (k, v) = v.first().unwrap();
215                        if variants.contains(&k.as_str()) {
216                            match v {
217                                Intermediate::Seq(v)
218                                | Intermediate::Tuple(v)
219                                | Intermediate::TupleStruct(v) => {
220                                    return visitor.visit_enum(EnumDeserializer::Tuple {
221                                        name: k,
222                                        content: v,
223                                        mode: self.mode,
224                                    })
225                                }
226                                Intermediate::Map(v) => {
227                                    return visitor.visit_enum(EnumDeserializer::Struct {
228                                        name: k,
229                                        content: EnumDeserializerStructContent::Entries(v),
230                                        mode: self.mode,
231                                    })
232                                }
233                                Intermediate::Struct(v) => {
234                                    return visitor.visit_enum(EnumDeserializer::Struct {
235                                        name: k,
236                                        content: EnumDeserializerStructContent::Fields(v),
237                                        mode: self.mode,
238                                    })
239                                }
240                                _ => {
241                                    return visitor.visit_enum(EnumDeserializer::NewType {
242                                        name: k,
243                                        content: v,
244                                        mode: self.mode,
245                                    })
246                                }
247                            }
248                        }
249                    }
250                }
251                _ => {}
252            }
253        }
254        self.deserialize_any(visitor)
255    }
256
257    forward_to_deserialize_any! {
258        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
259        bytes byte_buf option unit unit_struct seq tuple
260        tuple_struct map struct identifier ignored_any
261    }
262}
263
264#[derive(Debug)]
265pub struct SeqDeserializer<'de> {
266    values: &'de [Intermediate],
267    index: usize,
268    mode: DeserializeMode,
269}
270
271impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
272    type Error = Error;
273
274    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
275    where
276        T: DeserializeSeed<'de>,
277    {
278        if let Some(value) = self.values.get(self.index) {
279            self.index += 1;
280            return seed
281                .deserialize(Deserializer::from_intermediate(value, self.mode))
282                .map(Some);
283        }
284        Ok(None)
285    }
286}
287
288#[derive(Debug)]
289pub struct MapDeserializer<'de> {
290    values: &'de [(Intermediate, Intermediate)],
291    index: usize,
292    mode: DeserializeMode,
293}
294
295impl<'de> MapAccess<'de> for MapDeserializer<'de> {
296    type Error = Error;
297
298    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
299    where
300        K: DeserializeSeed<'de>,
301    {
302        if let Some((key, _)) = self.values.get(self.index) {
303            return seed
304                .deserialize(Deserializer::from_intermediate(key, self.mode))
305                .map(Some);
306        }
307        Ok(None)
308    }
309
310    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
311    where
312        V: DeserializeSeed<'de>,
313    {
314        if let Some((_, value)) = self.values.get(self.index) {
315            self.index += 1;
316            return seed.deserialize(Deserializer::from_intermediate(value, self.mode));
317        }
318        Err(Error::ExpectedMapEntry)
319    }
320
321    fn next_entry_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>>
322    where
323        K: DeserializeSeed<'de>,
324        V: DeserializeSeed<'de>,
325    {
326        if let Some((key, value)) = self.values.get(self.index) {
327            self.index += 1;
328            let key = kseed.deserialize(Deserializer::from_intermediate(key, self.mode))?;
329            let value = vseed.deserialize(Deserializer::from_intermediate(value, self.mode))?;
330            return Ok(Some((key, value)));
331        }
332        Ok(None)
333    }
334}
335
336#[derive(Debug)]
337pub struct StructDeserializer<'de> {
338    values: &'de [(String, Intermediate)],
339    index: usize,
340    mode: DeserializeMode,
341}
342
343impl<'de> MapAccess<'de> for StructDeserializer<'de> {
344    type Error = Error;
345
346    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
347    where
348        K: DeserializeSeed<'de>,
349    {
350        if let Some((key, _)) = self.values.get(self.index) {
351            return seed.deserialize(key.as_str().into_deserializer()).map(Some);
352        }
353        Ok(None)
354    }
355
356    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
357    where
358        V: DeserializeSeed<'de>,
359    {
360        if let Some((_, value)) = self.values.get(self.index) {
361            self.index += 1;
362            return seed.deserialize(Deserializer::from_intermediate(value, self.mode));
363        }
364        Err(Error::ExpectedStructField)
365    }
366
367    fn next_entry_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>>
368    where
369        K: DeserializeSeed<'de>,
370        V: DeserializeSeed<'de>,
371    {
372        if let Some((key, value)) = self.values.get(self.index) {
373            self.index += 1;
374            let key = kseed.deserialize(key.as_str().into_deserializer())?;
375            let value = vseed.deserialize(Deserializer::from_intermediate(value, self.mode))?;
376            return Ok(Some((key, value)));
377        }
378        Ok(None)
379    }
380}
381
382#[derive(Debug)]
383enum EnumDeserializerStructContent<'de> {
384    Entries(&'de [(Intermediate, Intermediate)]),
385    Fields(&'de [(String, Intermediate)]),
386}
387
388#[derive(Debug)]
389enum EnumDeserializer<'de> {
390    Unit {
391        name: &'de str,
392    },
393    NewType {
394        name: &'de str,
395        content: &'de Intermediate,
396        mode: DeserializeMode,
397    },
398    Tuple {
399        name: &'de str,
400        content: &'de [Intermediate],
401        mode: DeserializeMode,
402    },
403    Struct {
404        name: &'de str,
405        content: EnumDeserializerStructContent<'de>,
406        mode: DeserializeMode,
407    },
408}
409
410impl<'de> EnumDeserializer<'de> {
411    fn name(&self) -> &'de str {
412        match self {
413            Self::Unit { name }
414            | Self::NewType { name, .. }
415            | Self::Tuple { name, .. }
416            | Self::Struct { name, .. } => name,
417        }
418    }
419}
420
421impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
422    type Error = Error;
423    type Variant = Self;
424
425    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
426    where
427        V: DeserializeSeed<'de>,
428    {
429        let name = seed.deserialize(self.name().into_deserializer())?;
430        Ok((name, self))
431    }
432}
433
434impl<'de> VariantAccess<'de> for EnumDeserializer<'de> {
435    type Error = Error;
436
437    fn unit_variant(self) -> Result<()> {
438        if let EnumDeserializer::Unit { .. } = self {
439            return Ok(());
440        }
441        Err(Error::ExpectedUnitVariant)
442    }
443
444    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
445    where
446        T: DeserializeSeed<'de>,
447    {
448        if let EnumDeserializer::NewType { content, mode, .. } = self {
449            return seed.deserialize(Deserializer::from_intermediate(content, mode));
450        }
451        Err(Error::ExpectedNewTypeVariant)
452    }
453
454    fn tuple_variant<V>(self, _: usize, visitor: V) -> Result<V::Value>
455    where
456        V: Visitor<'de>,
457    {
458        if let EnumDeserializer::Tuple { content, mode, .. } = self {
459            return visitor.visit_seq(SeqDeserializer {
460                values: content,
461                index: 0,
462                mode,
463            });
464        }
465        Err(Error::ExpectedNewTypeVariant)
466    }
467
468    fn struct_variant<V>(self, _: &'static [&'static str], visitor: V) -> Result<V::Value>
469    where
470        V: Visitor<'de>,
471    {
472        if let EnumDeserializer::Struct { content, mode, .. } = self {
473            match content {
474                EnumDeserializerStructContent::Entries(content) => {
475                    return visitor.visit_map(MapDeserializer {
476                        values: content,
477                        index: 0,
478                        mode,
479                    })
480                }
481                EnumDeserializerStructContent::Fields(content) => {
482                    return visitor.visit_map(StructDeserializer {
483                        values: content,
484                        index: 0,
485                        mode,
486                    })
487                }
488            }
489        }
490        Err(Error::ExpectedStructVariant)
491    }
492}
493
494macro_rules! impl_visit {
495    ($name:ident, $type:ty) => {
496        fn $name<E>(self, value: $type) -> std::result::Result<Self::Value, E>
497        where
498            E: serde::de::Error,
499        {
500            Ok(value.into())
501        }
502    };
503}
504
505#[derive(Copy, Clone)]
506pub struct IntermediateVisitor;
507
508impl<'de> Visitor<'de> for IntermediateVisitor {
509    type Value = Intermediate;
510
511    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
512        formatter.write_str("intermediate data representation")
513    }
514
515    impl_visit!(visit_bool, bool);
516    impl_visit!(visit_i8, i8);
517    impl_visit!(visit_i16, i16);
518    impl_visit!(visit_i32, i32);
519    impl_visit!(visit_i64, i64);
520    impl_visit!(visit_i128, i128);
521    impl_visit!(visit_u8, u8);
522    impl_visit!(visit_u16, u16);
523    impl_visit!(visit_u32, u32);
524    impl_visit!(visit_u64, u64);
525    impl_visit!(visit_u128, u128);
526    impl_visit!(visit_f32, f32);
527    impl_visit!(visit_f64, f64);
528    impl_visit!(visit_char, char);
529
530    fn visit_str<E>(self, value: &str) -> std::result::Result<Self::Value, E>
531    where
532        E: serde::de::Error,
533    {
534        Ok(Intermediate::String(value.to_owned()))
535    }
536
537    fn visit_borrowed_str<E>(self, value: &'de str) -> std::result::Result<Self::Value, E>
538    where
539        E: serde::de::Error,
540    {
541        Ok(Intermediate::String(value.to_owned()))
542    }
543
544    fn visit_string<E>(self, value: String) -> std::result::Result<Self::Value, E>
545    where
546        E: serde::de::Error,
547    {
548        Ok(Intermediate::String(value))
549    }
550
551    fn visit_bytes<E>(self, value: &[u8]) -> std::result::Result<Self::Value, E>
552    where
553        E: serde::de::Error,
554    {
555        Ok(Intermediate::Bytes(value.to_owned()))
556    }
557
558    fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> std::result::Result<Self::Value, E>
559    where
560        E: serde::de::Error,
561    {
562        Ok(Intermediate::Bytes(value.to_owned()))
563    }
564
565    fn visit_byte_buf<E>(self, value: Vec<u8>) -> std::result::Result<Self::Value, E>
566    where
567        E: serde::de::Error,
568    {
569        Ok(Intermediate::Bytes(value))
570    }
571
572    fn visit_none<E>(self) -> std::result::Result<Self::Value, E>
573    where
574        E: serde::de::Error,
575    {
576        Ok(Intermediate::Option(None))
577    }
578
579    fn visit_some<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error>
580    where
581        D: serde::de::Deserializer<'de>,
582    {
583        Ok(Intermediate::Option(Some(Box::new(
584            deserializer.deserialize_any(IntermediateVisitor)?,
585        ))))
586    }
587
588    fn visit_unit<E>(self) -> std::result::Result<Self::Value, E>
589    where
590        E: serde::de::Error,
591    {
592        Ok(Intermediate::Unit)
593    }
594
595    fn visit_newtype_struct<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error>
596    where
597        D: serde::de::Deserializer<'de>,
598    {
599        Ok(Intermediate::NewTypeStruct(Box::new(
600            deserializer.deserialize_any(IntermediateVisitor)?,
601        )))
602    }
603
604    fn visit_seq<A>(self, mut access: A) -> std::result::Result<Self::Value, A::Error>
605    where
606        A: SeqAccess<'de>,
607    {
608        let mut result = Vec::with_capacity(access.size_hint().unwrap_or_default());
609        while let Some(v) = access.next_element()? {
610            result.push(v);
611        }
612        Ok(Intermediate::Seq(result))
613    }
614
615    fn visit_map<A>(self, mut access: A) -> std::result::Result<Self::Value, A::Error>
616    where
617        A: MapAccess<'de>,
618    {
619        let mut result = Vec::with_capacity(access.size_hint().unwrap_or_default());
620        while let Some((k, v)) = access.next_entry()? {
621            result.push((k, v));
622        }
623        Ok(Intermediate::Map(result))
624    }
625
626    // TODO: what do we do with this? this obviously can be called, but at least JSON tests don't
627    // do it, have to ask smart ppl what should i do to make it work, since neither serde docs nor
628    // book shows how this works for self-describing types.
629    // fn visit_enum<A>(self, mut access: A) -> std::result::Result<Self::Value, A::Error>
630    // where
631    //     A: EnumAccess<'de>,
632    // {
633    //     Err(serde::de::Error::invalid_type(Unexpected::Enum, &self))
634    // }
635}