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#[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 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#[inline]
507pub fn from_value<T: DeserializeOwned>(value: ConstValue) -> Result<T, DeserializerError> {
508 T::deserialize(value)
509}