config_maint/
de.rs

1use config::Config;
2use error::*;
3use serde::de;
4use std::collections::{HashMap, VecDeque};
5use std::iter::Enumerate;
6use value::{Table, Value, ValueKind};
7
8impl<'de> de::Deserializer<'de> for Value {
9    type Error = ConfigError;
10
11    #[inline]
12    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
13    where
14        V: de::Visitor<'de>,
15    {
16        // Deserialize based on the underlying type
17        match self.kind {
18            ValueKind::Nil => visitor.visit_unit(),
19            ValueKind::Integer(i) => visitor.visit_i64(i),
20            ValueKind::Boolean(b) => visitor.visit_bool(b),
21            ValueKind::Float(f) => visitor.visit_f64(f),
22            ValueKind::String(s) => visitor.visit_string(s),
23            ValueKind::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
24            ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map)),
25        }
26    }
27
28    #[inline]
29    fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
30        visitor.visit_bool(self.into_bool()?)
31    }
32
33    #[inline]
34    fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
35        // FIXME: This should *fail* if the value does not fit in the requets integer type
36        visitor.visit_i8(self.into_int()? as i8)
37    }
38
39    #[inline]
40    fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
41        // FIXME: This should *fail* if the value does not fit in the requets integer type
42        visitor.visit_i16(self.into_int()? as i16)
43    }
44
45    #[inline]
46    fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
47        // FIXME: This should *fail* if the value does not fit in the requets integer type
48        visitor.visit_i32(self.into_int()? as i32)
49    }
50
51    #[inline]
52    fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
53        visitor.visit_i64(self.into_int()?)
54    }
55
56    #[inline]
57    fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
58        // FIXME: This should *fail* if the value does not fit in the requets integer type
59        visitor.visit_u8(self.into_int()? as u8)
60    }
61
62    #[inline]
63    fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
64        // FIXME: This should *fail* if the value does not fit in the requets integer type
65        visitor.visit_u16(self.into_int()? as u16)
66    }
67
68    #[inline]
69    fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
70        // FIXME: This should *fail* if the value does not fit in the requets integer type
71        visitor.visit_u32(self.into_int()? as u32)
72    }
73
74    #[inline]
75    fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
76        // FIXME: This should *fail* if the value does not fit in the requets integer type
77        visitor.visit_u64(self.into_int()? as u64)
78    }
79
80    #[inline]
81    fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
82        visitor.visit_f32(self.into_float()? as f32)
83    }
84
85    #[inline]
86    fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
87        visitor.visit_f64(self.into_float()?)
88    }
89
90    #[inline]
91    fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
92        visitor.visit_string(self.into_str()?)
93    }
94
95    #[inline]
96    fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
97        visitor.visit_string(self.into_str()?)
98    }
99
100    #[inline]
101    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
102    where
103        V: de::Visitor<'de>,
104    {
105        // Match an explicit nil as None and everything else as Some
106        match self.kind {
107            ValueKind::Nil => visitor.visit_none(),
108            _ => visitor.visit_some(self),
109        }
110    }
111
112    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
113    where
114        V: de::Visitor<'de>,
115    {
116        visitor.visit_newtype_struct(self)
117    }
118
119    fn deserialize_enum<V>(
120        self,
121        name: &'static str,
122        variants: &'static [&'static str],
123        visitor: V,
124    ) -> Result<V::Value>
125    where
126        V: de::Visitor<'de>,
127    {
128        visitor.visit_enum(EnumAccess {
129            value: self,
130            name,
131            variants,
132        })
133    }
134
135    forward_to_deserialize_any! {
136        char seq
137        bytes byte_buf map struct unit
138        identifier ignored_any unit_struct tuple_struct tuple
139    }
140}
141
142struct StrDeserializer<'a>(&'a str);
143
144impl<'a> StrDeserializer<'a> {
145    fn new(key: &'a str) -> Self {
146        StrDeserializer(key)
147    }
148}
149
150impl<'de, 'a> de::Deserializer<'de> for StrDeserializer<'a> {
151    type Error = ConfigError;
152
153    #[inline]
154    fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
155        visitor.visit_str(self.0)
156    }
157
158    forward_to_deserialize_any! {
159        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
160        bytes byte_buf map struct unit enum newtype_struct
161        identifier ignored_any unit_struct tuple_struct tuple option
162    }
163}
164
165struct SeqAccess {
166    elements: Enumerate<::std::vec::IntoIter<Value>>,
167}
168
169impl SeqAccess {
170    fn new(elements: Vec<Value>) -> Self {
171        SeqAccess {
172            elements: elements.into_iter().enumerate(),
173        }
174    }
175}
176
177impl<'de> de::SeqAccess<'de> for SeqAccess {
178    type Error = ConfigError;
179
180    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
181    where
182        T: de::DeserializeSeed<'de>,
183    {
184        match self.elements.next() {
185            Some((idx, value)) => seed
186                .deserialize(value)
187                .map(Some)
188                .map_err(|e| e.prepend_index(idx)),
189            None => Ok(None),
190        }
191    }
192
193    fn size_hint(&self) -> Option<usize> {
194        match self.elements.size_hint() {
195            (lower, Some(upper)) if lower == upper => Some(upper),
196            _ => None,
197        }
198    }
199}
200
201struct MapAccess {
202    elements: VecDeque<(String, Value)>,
203}
204
205impl MapAccess {
206    fn new(table: HashMap<String, Value>) -> Self {
207        MapAccess {
208            elements: table.into_iter().collect(),
209        }
210    }
211}
212
213impl<'de> de::MapAccess<'de> for MapAccess {
214    type Error = ConfigError;
215
216    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
217    where
218        K: de::DeserializeSeed<'de>,
219    {
220        if let Some(&(ref key_s, _)) = self.elements.front() {
221            let key_de = Value::new(None, key_s as &str);
222            let key = de::DeserializeSeed::deserialize(seed, key_de)?;
223
224            Ok(Some(key))
225        } else {
226            Ok(None)
227        }
228    }
229
230    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
231    where
232        V: de::DeserializeSeed<'de>,
233    {
234        let (key, value) = self.elements.pop_front().unwrap();
235        de::DeserializeSeed::deserialize(seed, value).map_err(|e| e.prepend_key(key))
236    }
237}
238
239struct EnumAccess {
240    value: Value,
241    name: &'static str,
242    variants: &'static [&'static str],
243}
244
245impl EnumAccess {
246    fn variant_deserializer(&self, name: &str) -> Result<StrDeserializer> {
247        self.variants
248            .iter()
249            .find(|&&s| s == name)
250            .map(|&s| StrDeserializer(s))
251            .ok_or_else(|| self.no_constructor_error(name))
252    }
253
254    fn table_deserializer(&self, table: &Table) -> Result<StrDeserializer> {
255        if table.len() == 1 {
256            self.variant_deserializer(table.iter().next().unwrap().0)
257        } else {
258            Err(self.structural_error())
259        }
260    }
261
262    fn no_constructor_error(&self, supposed_variant: &str) -> ConfigError {
263        ConfigError::Message(format!(
264            "enum {} does not have variant constructor {}",
265            self.name, supposed_variant
266        ))
267    }
268
269    fn structural_error(&self) -> ConfigError {
270        ConfigError::Message(format!(
271            "value of enum {} should be represented by either string or table with exactly one key",
272            self.name
273        ))
274    }
275}
276
277impl<'de> de::EnumAccess<'de> for EnumAccess {
278    type Error = ConfigError;
279    type Variant = Self;
280
281    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
282    where
283        V: de::DeserializeSeed<'de>,
284    {
285        let value = {
286            let deserializer = match self.value.kind {
287                ValueKind::String(ref s) => self.variant_deserializer(s),
288                ValueKind::Table(ref t) => self.table_deserializer(&t),
289                _ => Err(self.structural_error()),
290            }?;
291            seed.deserialize(deserializer)?
292        };
293
294        Ok((value, self))
295    }
296}
297
298impl<'de> de::VariantAccess<'de> for EnumAccess {
299    type Error = ConfigError;
300
301    fn unit_variant(self) -> Result<()> {
302        Ok(())
303    }
304
305    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
306    where
307        T: de::DeserializeSeed<'de>,
308    {
309        match self.value.kind {
310            ValueKind::Table(t) => seed.deserialize(t.into_iter().next().unwrap().1),
311            _ => unreachable!(),
312        }
313    }
314
315    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
316    where
317        V: de::Visitor<'de>,
318    {
319        match self.value.kind {
320            ValueKind::Table(t) => {
321                de::Deserializer::deserialize_seq(t.into_iter().next().unwrap().1, visitor)
322            }
323            _ => unreachable!(),
324        }
325    }
326
327    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
328    where
329        V: de::Visitor<'de>,
330    {
331        match self.value.kind {
332            ValueKind::Table(t) => {
333                de::Deserializer::deserialize_map(t.into_iter().next().unwrap().1, visitor)
334            }
335            _ => unreachable!(),
336        }
337    }
338}
339
340impl<'de> de::Deserializer<'de> for Config {
341    type Error = ConfigError;
342
343    #[inline]
344    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
345    where
346        V: de::Visitor<'de>,
347    {
348        // Deserialize based on the underlying type
349        match self.cache.kind {
350            ValueKind::Nil => visitor.visit_unit(),
351            ValueKind::Integer(i) => visitor.visit_i64(i),
352            ValueKind::Boolean(b) => visitor.visit_bool(b),
353            ValueKind::Float(f) => visitor.visit_f64(f),
354            ValueKind::String(s) => visitor.visit_string(s),
355            ValueKind::Array(values) => visitor.visit_seq(SeqAccess::new(values)),
356            ValueKind::Table(map) => visitor.visit_map(MapAccess::new(map)),
357        }
358    }
359
360    #[inline]
361    fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
362        visitor.visit_bool(self.cache.into_bool()?)
363    }
364
365    #[inline]
366    fn deserialize_i8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
367        // FIXME: This should *fail* if the value does not fit in the requets integer type
368        visitor.visit_i8(self.cache.into_int()? as i8)
369    }
370
371    #[inline]
372    fn deserialize_i16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
373        // FIXME: This should *fail* if the value does not fit in the requets integer type
374        visitor.visit_i16(self.cache.into_int()? as i16)
375    }
376
377    #[inline]
378    fn deserialize_i32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
379        // FIXME: This should *fail* if the value does not fit in the requets integer type
380        visitor.visit_i32(self.cache.into_int()? as i32)
381    }
382
383    #[inline]
384    fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
385        visitor.visit_i64(self.cache.into_int()?)
386    }
387
388    #[inline]
389    fn deserialize_u8<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
390        // FIXME: This should *fail* if the value does not fit in the requets integer type
391        visitor.visit_u8(self.cache.into_int()? as u8)
392    }
393
394    #[inline]
395    fn deserialize_u16<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
396        // FIXME: This should *fail* if the value does not fit in the requets integer type
397        visitor.visit_u16(self.cache.into_int()? as u16)
398    }
399
400    #[inline]
401    fn deserialize_u32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
402        // FIXME: This should *fail* if the value does not fit in the requets integer type
403        visitor.visit_u32(self.cache.into_int()? as u32)
404    }
405
406    #[inline]
407    fn deserialize_u64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
408        // FIXME: This should *fail* if the value does not fit in the requets integer type
409        visitor.visit_u64(self.cache.into_int()? as u64)
410    }
411
412    #[inline]
413    fn deserialize_f32<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
414        visitor.visit_f32(self.cache.into_float()? as f32)
415    }
416
417    #[inline]
418    fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
419        visitor.visit_f64(self.cache.into_float()?)
420    }
421
422    #[inline]
423    fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
424        visitor.visit_string(self.cache.into_str()?)
425    }
426
427    #[inline]
428    fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
429        visitor.visit_string(self.cache.into_str()?)
430    }
431
432    #[inline]
433    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
434    where
435        V: de::Visitor<'de>,
436    {
437        // Match an explicit nil as None and everything else as Some
438        match self.cache.kind {
439            ValueKind::Nil => visitor.visit_none(),
440            _ => visitor.visit_some(self),
441        }
442    }
443
444    fn deserialize_enum<V>(
445        self,
446        name: &'static str,
447        variants: &'static [&'static str],
448        visitor: V,
449    ) -> Result<V::Value>
450    where
451        V: de::Visitor<'de>,
452    {
453        visitor.visit_enum(EnumAccess {
454            value: self.cache,
455            name,
456            variants,
457        })
458    }
459
460    forward_to_deserialize_any! {
461        char seq
462        bytes byte_buf map struct unit newtype_struct
463        identifier ignored_any unit_struct tuple_struct tuple
464    }
465}