async_graphql_value/
deserializer.rs

1use std::{fmt, vec};
2
3use indexmap::IndexMap;
4use serde::{
5    de::{
6        self, Deserialize, DeserializeOwned, DeserializeSeed, EnumAccess, Error as DeError,
7        IntoDeserializer, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor,
8    },
9    forward_to_deserialize_any,
10};
11
12use crate::{ConstValue, Name};
13
14/// This type represents errors that can occur when deserializing.
15#[derive(Debug)]
16pub struct DeserializerError(String);
17
18impl de::Error for DeserializerError {
19    #[inline]
20    fn custom<T: fmt::Display>(msg: T) -> Self {
21        DeserializerError(msg.to_string())
22    }
23}
24
25impl std::error::Error for DeserializerError {
26    #[inline]
27    fn description(&self) -> &str {
28        "Value deserializer error"
29    }
30}
31
32impl fmt::Display for DeserializerError {
33    #[inline]
34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35        match self {
36            DeserializerError(msg) => write!(f, "{}", msg),
37        }
38    }
39}
40
41impl From<de::value::Error> for DeserializerError {
42    #[inline]
43    fn from(e: de::value::Error) -> DeserializerError {
44        DeserializerError(e.to_string())
45    }
46}
47
48impl ConstValue {
49    #[inline]
50    fn unexpected(&self) -> Unexpected {
51        match self {
52            ConstValue::Null => Unexpected::Unit,
53            ConstValue::Number(_) => Unexpected::Other("number"),
54            ConstValue::String(v) => Unexpected::Str(v),
55            ConstValue::Boolean(v) => Unexpected::Bool(*v),
56            ConstValue::Binary(v) => Unexpected::Bytes(v),
57            ConstValue::Enum(v) => Unexpected::Str(v),
58            ConstValue::List(_) => Unexpected::Seq,
59            ConstValue::Object(_) => Unexpected::Map,
60        }
61    }
62}
63
64fn visit_array<'de, V>(array: Vec<ConstValue>, visitor: V) -> Result<V::Value, DeserializerError>
65where
66    V: Visitor<'de>,
67{
68    let len = array.len();
69    let mut deserializer = SeqDeserializer::new(array);
70    let seq = visitor.visit_seq(&mut deserializer)?;
71    let remaining = deserializer.iter.len();
72    if remaining == 0 {
73        Ok(seq)
74    } else {
75        Err(DeserializerError::invalid_length(
76            len,
77            &"fewer elements in array",
78        ))
79    }
80}
81
82fn visit_object<'de, V>(
83    object: IndexMap<Name, ConstValue>,
84    visitor: V,
85) -> Result<V::Value, DeserializerError>
86where
87    V: Visitor<'de>,
88{
89    let len = object.len();
90    let mut deserializer = MapDeserializer::new(object);
91    let map = visitor.visit_map(&mut deserializer)?;
92    let remaining = deserializer.iter.len();
93    if remaining == 0 {
94        Ok(map)
95    } else {
96        Err(DeserializerError::invalid_length(
97            len,
98            &"fewer elements in map",
99        ))
100    }
101}
102
103impl<'de> de::Deserializer<'de> for ConstValue {
104    type Error = DeserializerError;
105
106    #[inline]
107    fn deserialize_any<V>(self, visitor: V) -> Result<<V as Visitor<'de>>::Value, Self::Error>
108    where
109        V: Visitor<'de>,
110    {
111        match self {
112            ConstValue::Null => visitor.visit_unit(),
113            ConstValue::Number(v) => v
114                .deserialize_any(visitor)
115                .map_err(|err| DeserializerError(err.to_string())),
116            ConstValue::String(v) => visitor.visit_str(&v),
117            ConstValue::Boolean(v) => visitor.visit_bool(v),
118            ConstValue::Binary(bytes) => visitor.visit_bytes(&bytes),
119            ConstValue::Enum(v) => visitor.visit_str(v.as_str()),
120            ConstValue::List(v) => visit_array(v, visitor),
121            ConstValue::Object(v) => visit_object(v, visitor),
122        }
123    }
124
125    forward_to_deserialize_any! {
126        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
127        bytes byte_buf unit unit_struct seq tuple
128        tuple_struct map struct identifier ignored_any
129    }
130
131    #[inline]
132    fn deserialize_option<V>(self, visitor: V) -> Result<<V as Visitor<'de>>::Value, Self::Error>
133    where
134        V: Visitor<'de>,
135    {
136        match self {
137            ConstValue::Null => visitor.visit_none(),
138            _ => visitor.visit_some(self),
139        }
140    }
141
142    #[inline]
143    fn deserialize_newtype_struct<V>(
144        self,
145        _name: &'static str,
146        visitor: V,
147    ) -> Result<<V as Visitor<'de>>::Value, Self::Error>
148    where
149        V: Visitor<'de>,
150    {
151        visitor.visit_newtype_struct(self)
152    }
153
154    fn deserialize_enum<V>(
155        self,
156        _name: &'static str,
157        _variants: &'static [&'static str],
158        visitor: V,
159    ) -> Result<<V as Visitor<'de>>::Value, Self::Error>
160    where
161        V: Visitor<'de>,
162    {
163        let (variant, value) = match self {
164            ConstValue::Object(value) => {
165                let mut iter = value.into_iter();
166                let (variant, value) = match iter.next() {
167                    Some(v) => v,
168                    None => {
169                        return Err(serde::de::Error::invalid_value(
170                            Unexpected::Map,
171                            &"map with a single key",
172                        ));
173                    }
174                };
175                // enums are encoded in json as maps with a single key:value pair
176                if iter.next().is_some() {
177                    return Err(serde::de::Error::invalid_value(
178                        Unexpected::Map,
179                        &"map with a single key",
180                    ));
181                }
182                (variant, Some(value))
183            }
184            ConstValue::String(variant) => (Name::new(variant), None),
185            ConstValue::Enum(variant) => (variant, None),
186            other => {
187                return Err(DeserializerError::invalid_type(
188                    other.unexpected(),
189                    &"string or map",
190                ));
191            }
192        };
193
194        visitor.visit_enum(EnumDeserializer { variant, value })
195    }
196
197    #[inline]
198    fn is_human_readable(&self) -> bool {
199        true
200    }
201}
202
203struct EnumDeserializer {
204    variant: Name,
205    value: Option<ConstValue>,
206}
207
208impl<'de> EnumAccess<'de> for EnumDeserializer {
209    type Error = DeserializerError;
210    type Variant = VariantDeserializer;
211
212    #[inline]
213    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), DeserializerError>
214    where
215        V: DeserializeSeed<'de>,
216    {
217        let variant = self.variant.into_deserializer();
218        let visitor = VariantDeserializer { value: self.value };
219        seed.deserialize(variant).map(|v| (v, visitor))
220    }
221}
222
223impl IntoDeserializer<'_, DeserializerError> for ConstValue {
224    type Deserializer = Self;
225
226    fn into_deserializer(self) -> Self::Deserializer {
227        self
228    }
229}
230
231struct VariantDeserializer {
232    value: Option<ConstValue>,
233}
234
235impl<'de> VariantAccess<'de> for VariantDeserializer {
236    type Error = DeserializerError;
237
238    #[inline]
239    fn unit_variant(self) -> Result<(), DeserializerError> {
240        match self.value {
241            Some(value) => Deserialize::deserialize(value),
242            None => Ok(()),
243        }
244    }
245
246    #[inline]
247    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, DeserializerError>
248    where
249        T: DeserializeSeed<'de>,
250    {
251        match self.value {
252            Some(value) => seed.deserialize(value),
253            None => Err(DeserializerError::invalid_type(
254                Unexpected::UnitVariant,
255                &"newtype variant",
256            )),
257        }
258    }
259
260    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, DeserializerError>
261    where
262        V: Visitor<'de>,
263    {
264        match self.value {
265            Some(ConstValue::List(v)) => {
266                serde::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
267            }
268            Some(other) => Err(serde::de::Error::invalid_type(
269                other.unexpected(),
270                &"tuple variant",
271            )),
272            None => Err(DeserializerError::invalid_type(
273                Unexpected::UnitVariant,
274                &"tuple variant",
275            )),
276        }
277    }
278
279    fn struct_variant<V>(
280        self,
281        _fields: &'static [&'static str],
282        visitor: V,
283    ) -> Result<V::Value, DeserializerError>
284    where
285        V: Visitor<'de>,
286    {
287        match self.value {
288            Some(ConstValue::Object(v)) => {
289                serde::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
290            }
291            Some(other) => Err(DeserializerError::invalid_type(
292                other.unexpected(),
293                &"struct variant",
294            )),
295            None => Err(DeserializerError::invalid_type(
296                Unexpected::UnitVariant,
297                &"struct variant",
298            )),
299        }
300    }
301}
302
303struct SeqDeserializer {
304    iter: vec::IntoIter<ConstValue>,
305}
306
307impl SeqDeserializer {
308    fn new(vec: Vec<ConstValue>) -> Self {
309        SeqDeserializer {
310            iter: vec.into_iter(),
311        }
312    }
313}
314
315impl<'de> serde::Deserializer<'de> for SeqDeserializer {
316    type Error = DeserializerError;
317
318    #[inline]
319    fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, DeserializerError>
320    where
321        V: Visitor<'de>,
322    {
323        let len = self.iter.len();
324        if len == 0 {
325            visitor.visit_unit()
326        } else {
327            let ret = visitor.visit_seq(&mut self)?;
328            let remaining = self.iter.len();
329            if remaining == 0 {
330                Ok(ret)
331            } else {
332                Err(DeserializerError::invalid_length(
333                    len,
334                    &"fewer elements in array",
335                ))
336            }
337        }
338    }
339
340    forward_to_deserialize_any! {
341        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
342        bytes byte_buf option unit unit_struct newtype_struct seq tuple
343        tuple_struct map struct enum identifier ignored_any
344    }
345}
346
347impl<'de> SeqAccess<'de> for SeqDeserializer {
348    type Error = DeserializerError;
349
350    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeserializerError>
351    where
352        T: DeserializeSeed<'de>,
353    {
354        match self.iter.next() {
355            Some(value) => seed.deserialize(value).map(Some),
356            None => Ok(None),
357        }
358    }
359
360    #[inline]
361    fn size_hint(&self) -> Option<usize> {
362        match self.iter.size_hint() {
363            (lower, Some(upper)) if lower == upper => Some(upper),
364            _ => None,
365        }
366    }
367}
368
369struct MapDeserializer {
370    iter: <IndexMap<Name, ConstValue> as IntoIterator>::IntoIter,
371    value: Option<ConstValue>,
372}
373
374impl MapDeserializer {
375    #[inline]
376    fn new(map: IndexMap<Name, ConstValue>) -> Self {
377        MapDeserializer {
378            iter: map.into_iter(),
379            value: None,
380        }
381    }
382}
383
384impl<'de> MapAccess<'de> for MapDeserializer {
385    type Error = DeserializerError;
386
387    fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, DeserializerError>
388    where
389        T: DeserializeSeed<'de>,
390    {
391        match self.iter.next() {
392            Some((key, value)) => {
393                self.value = Some(value);
394                let key_de = MapKeyDeserializer { key };
395                seed.deserialize(key_de).map(Some)
396            }
397            None => Ok(None),
398        }
399    }
400
401    #[inline]
402    fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, DeserializerError>
403    where
404        T: DeserializeSeed<'de>,
405    {
406        match self.value.take() {
407            Some(value) => seed.deserialize(value),
408            None => Err(serde::de::Error::custom("value is missing")),
409        }
410    }
411
412    #[inline]
413    fn size_hint(&self) -> Option<usize> {
414        match self.iter.size_hint() {
415            (lower, Some(upper)) if lower == upper => Some(upper),
416            _ => None,
417        }
418    }
419}
420
421impl<'de> serde::Deserializer<'de> for MapDeserializer {
422    type Error = DeserializerError;
423
424    #[inline]
425    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, DeserializerError>
426    where
427        V: Visitor<'de>,
428    {
429        visitor.visit_map(self)
430    }
431
432    forward_to_deserialize_any! {
433        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
434        bytes byte_buf option unit unit_struct newtype_struct seq tuple
435        tuple_struct map struct enum identifier ignored_any
436    }
437}
438
439struct MapKeyDeserializer {
440    key: Name,
441}
442
443impl<'de> serde::Deserializer<'de> for MapKeyDeserializer {
444    type Error = DeserializerError;
445
446    #[inline]
447    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, DeserializerError>
448    where
449        V: Visitor<'de>,
450    {
451        NameDeserializer::new(self.key).deserialize_any(visitor)
452    }
453
454    #[inline]
455    fn deserialize_enum<V>(
456        self,
457        name: &'static str,
458        variants: &'static [&'static str],
459        visitor: V,
460    ) -> Result<V::Value, DeserializerError>
461    where
462        V: Visitor<'de>,
463    {
464        self.key
465            .into_deserializer()
466            .deserialize_enum(name, variants, visitor)
467    }
468
469    forward_to_deserialize_any! {
470        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
471        bytes byte_buf unit unit_struct seq tuple option newtype_struct
472        tuple_struct map struct identifier ignored_any
473    }
474}
475
476struct NameDeserializer {
477    value: Name,
478}
479
480impl NameDeserializer {
481    #[inline]
482    fn new(value: Name) -> Self {
483        NameDeserializer { value }
484    }
485}
486
487impl<'de> de::Deserializer<'de> for NameDeserializer {
488    type Error = DeserializerError;
489
490    #[inline]
491    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, DeserializerError>
492    where
493        V: de::Visitor<'de>,
494    {
495        visitor.visit_string(self.value.to_string())
496    }
497
498    forward_to_deserialize_any! {
499        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
500        bytes byte_buf option unit unit_struct newtype_struct seq tuple enum
501        tuple_struct map struct identifier ignored_any
502    }
503}
504
505/// Interpret a `ConstValue` as an instance of type `T`.
506#[inline]
507pub fn from_value<T: DeserializeOwned>(value: ConstValue) -> Result<T, DeserializerError> {
508    T::deserialize(value)
509}