serde_content/de/
enum.rs

1use crate::de::error::Unexpected;
2use crate::de::identifier::Identifier;
3use crate::de::Map;
4use crate::de::Seq;
5use crate::Data;
6use crate::DataType;
7use crate::Enum;
8use crate::Error;
9use crate::Expected;
10use crate::Value;
11use alloc::borrow::Cow;
12use alloc::borrow::ToOwned;
13use alloc::boxed::Box;
14use serde::de;
15use serde::Deserializer as _;
16
17#[cfg(feature = "std")]
18impl<'de> serde::de::IntoDeserializer<'de, Error> for Enum<'de> {
19    type Deserializer = crate::Deserializer<'de>;
20
21    fn into_deserializer(self) -> Self::Deserializer {
22        use crate::Deserializer;
23
24        Deserializer::new(Value::Enum(Box::new(self)))
25    }
26}
27
28pub(super) struct Deserializer<'de> {
29    // The name of the enum we are expecting
30    expected: Cow<'static, str>,
31    enum_box: Box<Enum<'de>>,
32    human_readable: bool,
33    coerce_numbers: bool,
34}
35
36impl<'de> de::EnumAccess<'de> for Deserializer<'de> {
37    type Error = Error;
38    type Variant = Self;
39
40    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
41    where
42        V: de::DeserializeSeed<'de>,
43    {
44        let variant = Identifier::new(
45            self.enum_box.variant.clone(),
46            self.enum_box.variant_index as u64,
47        );
48        seed.deserialize(variant).map(|v| (v, self))
49    }
50}
51
52impl<'de> de::VariantAccess<'de> for Deserializer<'de> {
53    type Error = Error;
54
55    fn unit_variant(self) -> Result<(), Self::Error> {
56        match self.enum_box.data {
57            Data::Unit => Ok(()),
58            _ => Err(self.enum_box.unexpected(Expected::Enum {
59                name: Some(self.expected.into_owned()),
60                typ: Some(DataType::Unit),
61            })),
62        }
63    }
64
65    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
66    where
67        T: de::DeserializeSeed<'de>,
68    {
69        match self.enum_box.data {
70            Data::NewType { value } => {
71                let deserializer = crate::Deserializer {
72                    value,
73                    human_readable: self.human_readable,
74                    coerce_numbers: self.coerce_numbers,
75                };
76                seed.deserialize(deserializer)
77            }
78            _ => Err(self.enum_box.unexpected(Expected::Enum {
79                name: Some(self.expected.into_owned()),
80                typ: Some(DataType::NewType),
81            })),
82        }
83    }
84
85    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
86    where
87        V: de::Visitor<'de>,
88    {
89        match self.enum_box.data {
90            Data::Tuple { values } => {
91                visitor.visit_seq(Seq::new(values, self.human_readable, self.coerce_numbers))
92            }
93            _ => Err(self.enum_box.unexpected(Expected::Enum {
94                name: Some(self.expected.into_owned()),
95                typ: Some(DataType::Tuple),
96            })),
97        }
98    }
99
100    fn struct_variant<V>(
101        self,
102        _fields: &'static [&'static str],
103        visitor: V,
104    ) -> Result<V::Value, Self::Error>
105    where
106        V: de::Visitor<'de>,
107    {
108        match self.enum_box.data {
109            Data::Struct { fields } => visitor.visit_map(Map::from((
110                fields,
111                self.human_readable,
112                self.coerce_numbers,
113            ))),
114            _ => Err(self.enum_box.unexpected(Expected::Enum {
115                name: Some(self.expected.into_owned()),
116                typ: Some(DataType::Struct),
117            })),
118        }
119    }
120}
121
122pub(super) fn visit_enum<'de, V>(
123    expected: Cow<'static, str>,
124    enum_box: Box<Enum<'de>>,
125    human_readable: bool,
126    coerce_numbers: bool,
127    visitor: V,
128) -> Result<V::Value, Error>
129where
130    V: de::Visitor<'de>,
131{
132    let deserializer = Deserializer {
133        expected,
134        enum_box,
135        human_readable,
136        coerce_numbers,
137    };
138    visitor.visit_enum(deserializer)
139}
140
141pub(super) struct Access<'de> {
142    // The name of the enum we are expecting
143    pub(super) expected: &'static str,
144    pub(super) name: Value<'de>,
145    pub(super) data: Option<Value<'de>>,
146    pub(super) human_readable: bool,
147    pub(super) coerce_numbers: bool,
148}
149
150impl<'de> de::EnumAccess<'de> for Access<'de> {
151    type Error = Error;
152    type Variant = VariantAccess<'de>;
153
154    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
155    where
156        V: de::DeserializeSeed<'de>,
157    {
158        let deserializer = crate::Deserializer {
159            value: self.name,
160            human_readable: self.human_readable,
161            coerce_numbers: self.coerce_numbers,
162        };
163        seed.deserialize(deserializer).map(|v| {
164            (
165                v,
166                VariantAccess {
167                    expected: self.expected,
168                    data: self.data,
169                    human_readable: self.human_readable,
170                    coerce_numbers: self.coerce_numbers,
171                },
172            )
173        })
174    }
175}
176
177pub(super) struct VariantAccess<'de> {
178    // The name of the enum we are expecting
179    expected: &'static str,
180    data: Option<Value<'de>>,
181    human_readable: bool,
182    coerce_numbers: bool,
183}
184
185impl<'de> de::VariantAccess<'de> for VariantAccess<'de> {
186    type Error = Error;
187
188    fn unit_variant(self) -> Result<(), Self::Error> {
189        match self.data {
190            None => Ok(()),
191            Some(v) => Err(v.unexpected(Expected::Enum {
192                name: Some(self.expected.to_owned()),
193                typ: Some(DataType::Unit),
194            })),
195        }
196    }
197
198    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
199    where
200        T: de::DeserializeSeed<'de>,
201    {
202        match self.data {
203            Some(value) => {
204                let deserializer = crate::Deserializer {
205                    value,
206                    human_readable: self.human_readable,
207                    coerce_numbers: self.coerce_numbers,
208                };
209                seed.deserialize(deserializer)
210            }
211            None => Err(Value::Unit.unexpected(Expected::Enum {
212                name: Some(self.expected.to_owned()),
213                typ: Some(DataType::NewType),
214            })),
215        }
216    }
217
218    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
219    where
220        V: de::Visitor<'de>,
221    {
222        match self.data {
223            Some(Value::Seq(seq)) => {
224                let deserializer = crate::Deserializer {
225                    value: Value::Seq(seq),
226                    human_readable: self.human_readable,
227                    coerce_numbers: self.coerce_numbers,
228                };
229                deserializer.deserialize_seq(visitor)
230            }
231            Some(v) => Err(v.unexpected(Expected::Enum {
232                name: Some(self.expected.to_owned()),
233                typ: Some(DataType::Tuple),
234            })),
235            None => Err(Value::Unit.unexpected(Expected::Enum {
236                name: Some(self.expected.to_owned()),
237                typ: Some(DataType::NewType),
238            })),
239        }
240    }
241
242    fn struct_variant<V>(
243        self,
244        _fields: &'static [&'static str],
245        visitor: V,
246    ) -> Result<V::Value, Self::Error>
247    where
248        V: de::Visitor<'de>,
249    {
250        match self.data {
251            Some(Value::Map(map)) => {
252                let deserializer = crate::Deserializer {
253                    value: Value::Map(map),
254                    human_readable: self.human_readable,
255                    coerce_numbers: self.coerce_numbers,
256                };
257                deserializer.deserialize_map(visitor)
258            }
259            Some(v) => Err(v.unexpected(Expected::Enum {
260                name: Some(self.expected.to_owned()),
261                typ: Some(DataType::Struct),
262            })),
263            None => Err(Value::Unit.unexpected(Expected::Enum {
264                name: Some(self.expected.to_owned()),
265                typ: Some(DataType::NewType),
266            })),
267        }
268    }
269}