Skip to main content

blazingly_json/
value_de.rs

1use crate::{Error, Result, Value};
2use serde::de::{
3    self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess,
4    Visitor,
5};
6use std::collections::btree_map;
7use std::vec;
8
9impl<'de> de::Deserializer<'de> for Value {
10    type Error = Error;
11
12    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
13        match self {
14            Self::Null => visitor.visit_unit(),
15            Self::Bool(value) => visitor.visit_bool(value),
16            Self::Number(value) if value.is_u64() => visitor.visit_u64(
17                value
18                    .as_u64()
19                    .expect("a u64 JSON number must contain a u64"),
20            ),
21            Self::Number(value) if value.is_i64() => visitor.visit_i64(
22                value
23                    .as_i64()
24                    .expect("an i64 JSON number must contain an i64"),
25            ),
26            Self::Number(value) => visitor.visit_f64(
27                value
28                    .as_f64()
29                    .expect("a JSON number must be representable as f64"),
30            ),
31            Self::String(value) => visitor.visit_string(value),
32            Self::Array(values) => visitor.visit_seq(ValueSeqAccess {
33                values: values.into_iter(),
34            }),
35            Self::Object(values) => visitor.visit_map(ValueMapAccess {
36                values: values.into_iter(),
37                pending: None,
38            }),
39        }
40    }
41
42    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
43        match self {
44            Self::Bool(value) => visitor.visit_bool(value),
45            other => Err(type_error("boolean", &other)),
46        }
47    }
48
49    fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
50        visitor.visit_i8(integer(&self)?)
51    }
52
53    fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
54        visitor.visit_i16(integer(&self)?)
55    }
56
57    fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
58        visitor.visit_i32(integer(&self)?)
59    }
60
61    fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
62        visitor.visit_i64(integer(&self)?)
63    }
64
65    fn deserialize_i128<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
66        visitor.visit_i128(integer(&self)?)
67    }
68
69    fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
70        visitor.visit_u8(unsigned(&self)?)
71    }
72
73    fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
74        visitor.visit_u16(unsigned(&self)?)
75    }
76
77    fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
78        visitor.visit_u32(unsigned(&self)?)
79    }
80
81    fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
82        visitor.visit_u64(unsigned(&self)?)
83    }
84
85    fn deserialize_u128<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
86        visitor.visit_u128(unsigned(&self)?)
87    }
88
89    fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
90        #[allow(clippy::cast_possible_truncation)]
91        let value = float(&self)? as f32;
92        visitor.visit_f32(value)
93    }
94
95    fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
96        visitor.visit_f64(float(&self)?)
97    }
98
99    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
100        match self {
101            Self::String(value) => {
102                let mut characters = value.chars();
103                let character = characters
104                    .next()
105                    .ok_or_else(|| Error::message("expected one character"))?;
106                if characters.next().is_some() {
107                    return Err(Error::message("expected one character"));
108                }
109                visitor.visit_char(character)
110            }
111            other => Err(type_error("string", &other)),
112        }
113    }
114
115    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
116        match self {
117            Self::String(value) => visitor.visit_string(value),
118            other => Err(type_error("string", &other)),
119        }
120    }
121
122    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
123        self.deserialize_str(visitor)
124    }
125
126    fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
127        self.deserialize_seq(visitor)
128    }
129
130    fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
131        self.deserialize_seq(visitor)
132    }
133
134    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
135        if self.is_null() {
136            visitor.visit_none()
137        } else {
138            visitor.visit_some(self)
139        }
140    }
141
142    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
143        if self.is_null() {
144            visitor.visit_unit()
145        } else {
146            Err(type_error("null", &self))
147        }
148    }
149
150    fn deserialize_unit_struct<V: Visitor<'de>>(
151        self,
152        _name: &'static str,
153        visitor: V,
154    ) -> Result<V::Value> {
155        self.deserialize_unit(visitor)
156    }
157
158    fn deserialize_newtype_struct<V: Visitor<'de>>(
159        self,
160        _name: &'static str,
161        visitor: V,
162    ) -> Result<V::Value> {
163        visitor.visit_newtype_struct(self)
164    }
165
166    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
167        match self {
168            Self::Array(values) => visitor.visit_seq(ValueSeqAccess {
169                values: values.into_iter(),
170            }),
171            other => Err(type_error("array", &other)),
172        }
173    }
174
175    fn deserialize_tuple<V: Visitor<'de>>(self, _length: usize, visitor: V) -> Result<V::Value> {
176        self.deserialize_seq(visitor)
177    }
178
179    fn deserialize_tuple_struct<V: Visitor<'de>>(
180        self,
181        _name: &'static str,
182        length: usize,
183        visitor: V,
184    ) -> Result<V::Value> {
185        self.deserialize_tuple(length, visitor)
186    }
187
188    fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
189        match self {
190            Self::Object(values) => visitor.visit_map(ValueMapAccess {
191                values: values.into_iter(),
192                pending: None,
193            }),
194            other => Err(type_error("object", &other)),
195        }
196    }
197
198    fn deserialize_struct<V: Visitor<'de>>(
199        self,
200        _name: &'static str,
201        _fields: &'static [&'static str],
202        visitor: V,
203    ) -> Result<V::Value> {
204        self.deserialize_map(visitor)
205    }
206
207    fn deserialize_enum<V: Visitor<'de>>(
208        self,
209        _name: &'static str,
210        _variants: &'static [&'static str],
211        visitor: V,
212    ) -> Result<V::Value> {
213        match self {
214            Self::String(variant) => visitor.visit_enum(variant.into_deserializer()),
215            Self::Object(mut values) if values.len() == 1 => {
216                let (variant, value) = values.pop_first().expect("length was checked");
217                visitor.visit_enum(ValueEnumAccess { variant, value })
218            }
219            other => Err(type_error("enum string or one-entry object", &other)),
220        }
221    }
222
223    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
224        self.deserialize_string(visitor)
225    }
226
227    fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
228        visitor.visit_unit()
229    }
230}
231
232fn integer<T: TryFrom<i64>>(value: &Value) -> Result<T> {
233    let value = value
234        .as_i64()
235        .ok_or_else(|| type_error("signed integer", value))?;
236    T::try_from(value).map_err(|_| Error::message("integer is out of range"))
237}
238
239fn unsigned<T: TryFrom<u64>>(value: &Value) -> Result<T> {
240    let value = value
241        .as_u64()
242        .ok_or_else(|| type_error("unsigned integer", value))?;
243    T::try_from(value).map_err(|_| Error::message("integer is out of range"))
244}
245
246fn float(value: &Value) -> Result<f64> {
247    value.as_f64().ok_or_else(|| type_error("number", value))
248}
249
250fn type_error(expected: &str, value: &Value) -> Error {
251    let actual = match value {
252        Value::Null => "null",
253        Value::Bool(_) => "boolean",
254        Value::Number(_) => "number",
255        Value::String(_) => "string",
256        Value::Array(_) => "array",
257        Value::Object(_) => "object",
258    };
259    Error::message(format!("expected {expected}, found {actual}"))
260}
261
262struct ValueSeqAccess {
263    values: vec::IntoIter<Value>,
264}
265
266impl<'de> SeqAccess<'de> for ValueSeqAccess {
267    type Error = Error;
268
269    fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
270        self.values
271            .next()
272            .map(|value| seed.deserialize(value))
273            .transpose()
274    }
275
276    fn size_hint(&self) -> Option<usize> {
277        Some(self.values.len())
278    }
279}
280
281struct ValueMapAccess {
282    values: btree_map::IntoIter<String, Value>,
283    pending: Option<Value>,
284}
285
286impl<'de> MapAccess<'de> for ValueMapAccess {
287    type Error = Error;
288
289    fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
290        let Some((key, value)) = self.values.next() else {
291            return Ok(None);
292        };
293        self.pending = Some(value);
294        seed.deserialize(key.into_deserializer()).map(Some)
295    }
296
297    fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
298        seed.deserialize(
299            self.pending
300                .take()
301                .ok_or_else(|| Error::message("map value has no key"))?,
302        )
303    }
304
305    fn size_hint(&self) -> Option<usize> {
306        Some(self.values.len())
307    }
308}
309
310struct ValueEnumAccess {
311    variant: String,
312    value: Value,
313}
314
315impl<'de> EnumAccess<'de> for ValueEnumAccess {
316    type Error = Error;
317    type Variant = ValueVariantAccess;
318
319    fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
320        let variant = seed.deserialize(serde::de::value::StringDeserializer::<Error>::new(
321            self.variant,
322        ))?;
323        Ok((variant, ValueVariantAccess { value: self.value }))
324    }
325}
326
327struct ValueVariantAccess {
328    value: Value,
329}
330
331impl<'de> VariantAccess<'de> for ValueVariantAccess {
332    type Error = Error;
333
334    fn unit_variant(self) -> Result<()> {
335        de::Deserialize::deserialize(self.value)
336    }
337
338    fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
339        seed.deserialize(self.value)
340    }
341
342    fn tuple_variant<V: Visitor<'de>>(self, length: usize, visitor: V) -> Result<V::Value> {
343        de::Deserializer::deserialize_tuple(self.value, length, visitor)
344    }
345
346    fn struct_variant<V: Visitor<'de>>(
347        self,
348        fields: &'static [&'static str],
349        visitor: V,
350    ) -> Result<V::Value> {
351        de::Deserializer::deserialize_struct(self.value, "", fields, visitor)
352    }
353}