path_value/value/
de.rs

1use std::collections::{HashMap, VecDeque};
2use std::convert::TryInto;
3use std::iter::Enumerate;
4
5use num_traits::ToPrimitive;
6use serde::de;
7
8use crate::error::{Error, Result};
9use crate::value::Value;
10
11impl<'de> de::Deserializer<'de> for Value {
12    type Error = Error;
13
14    #[inline]
15    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
16    where
17        V: de::Visitor<'de>,
18    {
19        // Deserialize based on the underlying type
20        match self {
21            Value::Nil => visitor.visit_unit(),
22            Value::Integer(i) => match i.to_i64() {
23                Some(v) => visitor.visit_i64(v),
24                None => Err(Error::too_large(i)),
25            },
26            Value::Boolean(b) => visitor.visit_bool(b),
27            Value::Float(f) => visitor.visit_f64(f),
28            Value::String(s) => visitor.visit_string(s),
29            Value::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
30            Value::Map(map) => visitor.visit_map(MapAccess::new(map)),
31        }
32    }
33
34    #[inline]
35    fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
36        visitor.visit_bool(self.try_into()?)
37    }
38
39    #[inline]
40    fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
41        visitor.visit_i8(self.try_into()?)
42    }
43
44    #[inline]
45    fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
46        visitor.visit_i16(self.try_into()?)
47    }
48
49    #[inline]
50    fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
51        visitor.visit_i32(self.try_into()?)
52    }
53
54    #[inline]
55    fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
56        visitor.visit_i64(self.try_into()?)
57    }
58
59    #[inline]
60    fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
61        visitor.visit_u8(self.try_into()?)
62    }
63
64    #[inline]
65    fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
66        visitor.visit_u16(self.try_into()?)
67    }
68
69    #[inline]
70    fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
71        visitor.visit_u32(self.try_into()?)
72    }
73
74    #[inline]
75    fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
76        visitor.visit_u64(self.try_into()?)
77    }
78
79    #[inline]
80    fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
81        visitor.visit_f32(self.try_into()?)
82    }
83
84    #[inline]
85    fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
86        visitor.visit_f64(self.try_into()?)
87    }
88
89    #[inline]
90    fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
91        visitor.visit_string(self.try_into()?)
92    }
93
94    #[inline]
95    fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
96        visitor.visit_string(self.try_into()?)
97    }
98
99    #[inline]
100    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
101    where
102        V: de::Visitor<'de>,
103    {
104        // Match an explicit nil as None and everything else as Some
105        match self {
106            Value::Nil => visitor.visit_none(),
107            _ => visitor.visit_some(self),
108        }
109    }
110
111    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
112    where
113        V: de::Visitor<'de>,
114    {
115        visitor.visit_newtype_struct(self)
116    }
117
118    fn deserialize_enum<V>(
119        self,
120        name: &'static str,
121        variants: &'static [&'static str],
122        visitor: V,
123    ) -> Result<V::Value>
124    where
125        V: de::Visitor<'de>,
126    {
127        visitor.visit_enum(EnumAccess {
128            value: self,
129            name,
130            variants,
131        })
132    }
133
134    forward_to_deserialize_any! {
135        char seq
136        bytes byte_buf map struct unit
137        identifier ignored_any unit_struct tuple_struct tuple
138    }
139}
140
141struct StrDeserializer<'a>(&'a str);
142
143impl<'a> StrDeserializer<'a> {
144    fn new(key: &'a str) -> Self {
145        StrDeserializer(key)
146    }
147}
148
149impl<'de, 'a> de::Deserializer<'de> for StrDeserializer<'a> {
150    type Error = Error;
151
152    #[inline]
153    fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
154        visitor.visit_str(self.0)
155    }
156
157    forward_to_deserialize_any! {
158        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
159        bytes byte_buf map struct unit enum newtype_struct
160        identifier ignored_any unit_struct tuple_struct tuple option
161    }
162}
163
164struct SeqAccess {
165    elements: Enumerate<::std::vec::IntoIter<Value>>,
166}
167
168impl SeqAccess {
169    fn new(elements: Vec<Value>) -> Self {
170        SeqAccess {
171            elements: elements.into_iter().enumerate(),
172        }
173    }
174}
175
176impl<'de> de::SeqAccess<'de> for SeqAccess {
177    type Error = Error;
178
179    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
180    where
181        T: de::DeserializeSeed<'de>,
182    {
183        match self.elements.next() {
184            Some((idx, value)) => seed.deserialize(value).map(Some),
185            None => Ok(None),
186        }
187    }
188
189    fn size_hint(&self) -> Option<usize> {
190        match self.elements.size_hint() {
191            (lower, Some(upper)) if lower == upper => Some(upper),
192            _ => None,
193        }
194    }
195}
196
197struct MapAccess {
198    elements: VecDeque<(String, Value)>,
199}
200
201impl MapAccess {
202    fn new(table: HashMap<String, Value>) -> Self {
203        MapAccess {
204            elements: table.into_iter().collect(),
205        }
206    }
207}
208
209impl<'de> de::MapAccess<'de> for MapAccess {
210    type Error = Error;
211
212    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
213    where
214        K: de::DeserializeSeed<'de>,
215    {
216        if let Some(&(ref key_s, _)) = self.elements.front() {
217            let key_de = Value::String(key_s.clone());
218            let key = de::DeserializeSeed::deserialize(seed, key_de)?;
219
220            Ok(Some(key))
221        } else {
222            Ok(None)
223        }
224    }
225
226    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
227    where
228        V: de::DeserializeSeed<'de>,
229    {
230        let (key, value) = self.elements.pop_front().unwrap();
231        de::DeserializeSeed::deserialize(seed, value)
232    }
233}
234
235struct EnumAccess {
236    value: Value,
237    name: &'static str,
238    variants: &'static [&'static str],
239}
240
241impl EnumAccess {
242    fn variant_deserializer(&self, name: &str) -> Result<StrDeserializer> {
243        self.variants
244            .iter()
245            .find(|s| **s == name)
246            .map(|s| StrDeserializer(*s))
247            .ok_or_else(|| self.no_constructor_error(name))
248    }
249
250    fn table_deserializer(&self, table: &HashMap<String, Value>) -> Result<StrDeserializer> {
251        if table.len() == 1 {
252            self.variant_deserializer(table.iter().next().unwrap().0)
253        } else {
254            Err(self.structural_error())
255        }
256    }
257
258    fn no_constructor_error(&self, supposed_variant: &str) -> Error {
259        Error::serde(format!(
260            "enum {} does not have variant constructor {}",
261            self.name, supposed_variant
262        ))
263    }
264
265    fn structural_error(&self) -> Error {
266        Error::serde(format!(
267            "value of enum {} should be represented by either string or table with exactly one key",
268            self.name
269        ))
270    }
271}
272
273impl<'de> de::EnumAccess<'de> for EnumAccess {
274    type Error = Error;
275    type Variant = Self;
276
277    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
278    where
279        V: de::DeserializeSeed<'de>,
280    {
281        let value = {
282            let deserializer = match self.value {
283                Value::String(ref s) => self.variant_deserializer(s),
284                Value::Map(ref t) => self.table_deserializer(&t),
285                _ => Err(self.structural_error()),
286            }?;
287            seed.deserialize(deserializer)?
288        };
289
290        Ok((value, self))
291    }
292}
293
294impl<'de> de::VariantAccess<'de> for EnumAccess {
295    type Error = Error;
296
297    fn unit_variant(self) -> Result<()> {
298        Ok(())
299    }
300
301    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
302    where
303        T: de::DeserializeSeed<'de>,
304    {
305        match self.value {
306            Value::Map(map) => seed.deserialize(map.into_iter().next().unwrap().1),
307            _ => unreachable!(),
308        }
309    }
310
311    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
312    where
313        V: de::Visitor<'de>,
314    {
315        match self.value {
316            Value::Map(t) => {
317                de::Deserializer::deserialize_seq(t.into_iter().next().unwrap().1, visitor)
318            }
319            _ => unreachable!(),
320        }
321    }
322
323    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
324    where
325        V: de::Visitor<'de>,
326    {
327        match self.value {
328            Value::Map(t) => {
329                de::Deserializer::deserialize_map(t.into_iter().next().unwrap().1, visitor)
330            }
331            _ => unreachable!(),
332        }
333    }
334}