litl_val/to_other/deserializer/
val_ref.rs

1use serde::{
2    de::{
3        value::{MapDeserializer, SeqDeserializer},
4        Error, IntoDeserializer, Unexpected, Visitor,
5    },
6    forward_to_deserialize_any, Deserializer,
7};
8
9use super::ValDeserializerError;
10use crate::ValRef;
11
12impl<'de> Deserializer<'de> for ValRef<'de> {
13    type Error = ValDeserializerError;
14
15    #[inline]
16    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
17    where
18        V: serde::de::Visitor<'de>,
19    {
20        match self {
21            ValRef::Null => visitor.visit_none(),
22            ValRef::Bool(b) => visitor.visit_bool(b),
23            ValRef::Number(n) => {
24                // weird hack for deserializing floats when integers are expected
25                // if floats are expected, this should still work!
26                let float = n.into_inner();
27                if float.fract() == 0.0 {
28                    visitor.visit_i64(float as i64)
29                } else {
30                    visitor.visit_f64(float)
31                }
32            }
33            ValRef::String(s) => visitor.visit_str(s.as_ref()),
34            ValRef::Array(a) => {
35                visitor.visit_seq(SeqDeserializer::new(a.iter().map(|v| v.direct_ref())))
36            }
37            ValRef::Object(o) => visitor.visit_map(MapDeserializer::new(
38                o.0.iter().map(|(k, v)| (k.as_str(), v.direct_ref())),
39            )),
40        }
41    }
42
43    forward_to_deserialize_any! {
44        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
45        bytes byte_buf unit unit_struct newtype_struct seq tuple
46        tuple_struct map struct identifier ignored_any
47    }
48
49    #[inline]
50    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
51    where
52        V: Visitor<'de>,
53    {
54        match self {
55            ValRef::Null => visitor.visit_none(),
56            _ => visitor.visit_some(self),
57        }
58    }
59
60    #[inline]
61    fn deserialize_enum<V>(
62        self,
63        _name: &str,
64        _variants: &'static [&'static str],
65        visitor: V,
66    ) -> Result<V::Value, Self::Error>
67    where
68        V: Visitor<'de>,
69    {
70        deserialize_val_ref_enum(self, visitor)
71    }
72}
73
74#[inline]
75pub fn deserialize_val_ref_enum<'de, V: Visitor<'de>>(
76    val: ValRef<'de>,
77    visitor: V,
78) -> Result<V::Value, ValDeserializerError> {
79    let (variant, value) = match val {
80        ValRef::Object(value) => {
81            let mut iter = value.0.iter();
82            let (variant, value) = match iter.next() {
83                Some((k, v)) => (k.as_str().to_string(), v),
84                None => {
85                    return Err(ValDeserializerError::invalid_value(
86                        Unexpected::Map,
87                        &"map with a single key",
88                    ));
89                }
90            };
91            // enums are encoded in json as maps with a single key:value pair
92            if iter.next().is_some() {
93                return Err(ValDeserializerError::invalid_value(
94                    Unexpected::Map,
95                    &"map with a single key",
96                ));
97            }
98            (variant, Some(value))
99        }
100        ValRef::String(variant) => (variant.to_string(), None),
101        other => {
102            return Err(ValDeserializerError::invalid_type(
103                Unexpected::Other(&format!("{:?}", other)),
104                &"string or map",
105            ));
106        }
107    };
108
109    // TODO: save a (deep) clone in the future by implementing borrowing EnumDeserializer
110    visitor.visit_enum(super::enum_de::EnumDeserializer {
111        variant,
112        value: value.cloned(),
113    })
114}
115
116impl<'de> IntoDeserializer<'de> for ValRef<'de> {
117    type Deserializer = Self;
118
119    fn into_deserializer(self) -> Self::Deserializer {
120        self
121    }
122}