figment/value/
de.rs

1use std::fmt;
2use std::result;
3use std::cell::Cell;
4use std::marker::PhantomData;
5use std::borrow::Cow;
6
7use serde::Deserialize;
8use serde::de::{self, Deserializer, IntoDeserializer, Visitor};
9use serde::de::{SeqAccess, MapAccess, VariantAccess};
10
11use crate::Figment;
12use crate::error::{Error, Kind, Result};
13use crate::value::{Value, Num, Empty, Dict, Tag};
14
15pub trait Interpreter {
16    fn interpret_as_bool(v: &Value) -> Cow<'_, Value> {
17        Cow::Borrowed(v)
18    }
19
20    fn interpret_as_num(v: &Value) -> Cow<'_, Value> {
21        Cow::Borrowed(v)
22    }
23}
24
25pub struct DefaultInterpreter;
26impl Interpreter for DefaultInterpreter { }
27
28pub struct LossyInterpreter;
29impl Interpreter for LossyInterpreter {
30    fn interpret_as_bool(v: &Value) -> Cow<'_, Value> {
31        v.to_bool_lossy()
32            .map(|b| Cow::Owned(Value::Bool(v.tag(), b)))
33            .unwrap_or(Cow::Borrowed(v))
34    }
35
36    fn interpret_as_num(v: &Value) -> Cow<'_, Value> {
37        v.to_num_lossy()
38            .map(|n| Cow::Owned(Value::Num(v.tag(), n)))
39            .unwrap_or(Cow::Borrowed(v))
40    }
41}
42
43pub struct ConfiguredValueDe<'c, I = DefaultInterpreter> {
44    pub config: &'c Figment,
45    pub value: &'c Value,
46    pub readable: Cell<bool>,
47    _phantom: PhantomData<I>
48}
49
50impl<'c, I: Interpreter> ConfiguredValueDe<'c, I> {
51    pub fn from(config: &'c Figment, value: &'c Value) -> Self {
52        Self { config, value, readable: Cell::from(true), _phantom: PhantomData }
53    }
54}
55
56/// Like [`serde::forward_to_deserialize_any`] but applies `$apply` to
57/// `&self` first, then calls `deserialize_any()` on the returned value, and
58/// finally maps any error produced using `$errmap`:
59///   - $apply(&self).deserialize_any(visitor).map_err($errmap)
60macro_rules! apply_then_forward_to_deserialize_any {
61    ( $( $($f:ident),+ => |$this:pat| $apply:expr, $errmap:expr),* $(,)? ) => {
62        $(
63            $(
64                fn $f<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
65                    let $this = &self;
66                    $apply.deserialize_any(visitor).map_err($errmap)
67                }
68            )+
69        )*
70    }
71}
72
73impl<'de: 'c, 'c, I: Interpreter> Deserializer<'de> for ConfiguredValueDe<'c, I> {
74    type Error = Error;
75
76    fn deserialize_any<V>(self, v: V) -> Result<V::Value>
77        where V: de::Visitor<'de>
78    {
79        let maker = |v| Self::from(self.config, v);
80        let result = match *self.value {
81            Value::String(_, ref s) => v.visit_str(s),
82            Value::Char(_, c) => v.visit_char(c),
83            Value::Bool(_, b) => v.visit_bool(b),
84            Value::Num(_, n) => n.deserialize_any(v),
85            Value::Empty(_, e) => e.deserialize_any(v),
86            Value::Dict(_, ref map) => v.visit_map(MapDe::new(map, maker)),
87            Value::Array(_, ref seq) => v.visit_seq(SeqDe::new(seq, maker)),
88        };
89
90        result.map_err(|e| e.retagged(self.value.tag()).resolved(self.config))
91    }
92
93    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
94        where V: Visitor<'de>
95    {
96        let (config, tag) = (self.config, self.value.tag());
97        let result = match self.value {
98            Value::Empty(_, val) => val.deserialize_any(visitor),
99            _ => visitor.visit_some(self)
100        };
101
102        result.map_err(|e| e.retagged(tag).resolved(&config))
103    }
104
105    fn deserialize_struct<V: Visitor<'de>>(
106        self,
107        name: &'static str,
108        _fields: &'static [&'static str],
109        visitor: V
110    ) -> Result<V::Value> {
111        use crate::value::magic::*;
112
113        let (config, tag) = (self.config, self.value.tag());
114        let result = match name {
115            Value::NAME => Value::deserialize_from(self, visitor),
116            RelativePathBuf::NAME => RelativePathBuf::deserialize_from(self, visitor),
117            Tagged::<()>::NAME => Tagged::<()>::deserialize_from(self, visitor),
118            // SelectedProfile::NAME => SelectedProfile::deserialize_from(self, visitor),
119            _ => self.deserialize_any(visitor)
120        };
121
122        result.map_err(|e| e.retagged(tag).resolved(config))
123    }
124
125    fn deserialize_enum<V: Visitor<'de>>(
126        self,
127        _: &'static str,
128        _: &'static [&'static str],
129        v: V,
130    ) -> Result<V::Value> {
131        use serde::de::value::MapAccessDeserializer;
132
133        let (config, tag) = (self.config, self.value.tag());
134        let result = match self.value {
135            Value::String(_, s) => v.visit_enum((&**s).into_deserializer()),
136            Value::Dict(_, ref map) => {
137                let maker = |v| Self::from(self.config, v);
138                let map_access = MapDe::new(map, maker);
139                v.visit_enum(MapAccessDeserializer::new(map_access))
140            }
141            Value::Num(_, n) if n.to_u32().is_some() => {
142                let tag = n.to_u32().unwrap();
143                v.visit_enum(tag.into_deserializer())
144            }
145            _ => self.deserialize_any(v)
146        };
147
148        result.map_err(|e| e.retagged(tag).resolved(&config))
149    }
150
151    fn deserialize_newtype_struct<V: Visitor<'de>>(
152        self,
153        _name: &'static str,
154        visitor: V,
155    ) -> Result<V::Value> {
156        visitor.visit_newtype_struct(self)
157    }
158
159    fn is_human_readable(&self) -> bool {
160        let val = self.readable.get();
161        self.readable.set(!val);
162        val
163    }
164
165    apply_then_forward_to_deserialize_any! {
166        deserialize_bool =>
167            |de| I::interpret_as_bool(de.value),
168            |e| e.retagged(de.value.tag()).resolved(de.config),
169        deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64,
170        deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64,
171        deserialize_f32, deserialize_f64 =>
172            |de| I::interpret_as_num(de.value),
173            |e| e.retagged(de.value.tag()).resolved(de.config),
174    }
175
176    serde::forward_to_deserialize_any! {
177        char str
178        string seq bytes byte_buf map unit
179        ignored_any unit_struct tuple_struct tuple identifier
180    }
181}
182
183use std::collections::btree_map::Iter;
184
185pub struct MapDe<'m, D, F: Fn(&'m Value) -> D> {
186    iter: Iter<'m, String, Value>,
187    pair: Option<(&'m String, &'m Value)>,
188    make_deserializer: F,
189}
190
191impl<'m, D, F: Fn(&'m Value) -> D> MapDe<'m, D, F> {
192    pub fn new(map: &'m Dict, maker: F) -> Self {
193        MapDe { iter: map.iter(), pair: None, make_deserializer: maker }
194    }
195}
196
197impl<'m, 'de, D, F> de::MapAccess<'de> for MapDe<'m, D, F>
198    where D: Deserializer<'de, Error = Error>, F: Fn(&'m Value) -> D,
199{
200    type Error = Error;
201
202    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
203        where K: de::DeserializeSeed<'de>
204    {
205        if let Some((k, v)) = self.iter.next() {
206            let result = seed.deserialize(k.as_str().into_deserializer())
207                .map_err(|e: Error| e.prefixed(k).retagged(v.tag()))
208                .map(Some);
209
210            self.pair = Some((k, v));
211            result
212        } else {
213            Ok(None)
214        }
215    }
216
217    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
218        where V: de::DeserializeSeed<'de>
219    {
220        let (key, value) = self.pair.take().expect("visit_value called before visit_key");
221        let tag = value.tag();
222        seed.deserialize((self.make_deserializer)(value))
223            .map_err(|e: Error| e.prefixed(key).retagged(tag))
224    }
225}
226
227pub struct SeqDe<'v, D, F: Fn(&'v Value) -> D> {
228    iter: std::iter::Enumerate<std::slice::Iter<'v, Value>>,
229    len: usize,
230    make_deserializer: F,
231}
232
233impl<'v, D, F: Fn(&'v Value) -> D> SeqDe<'v, D, F> {
234    pub fn new(seq: &'v [Value], maker: F) -> Self {
235        SeqDe { len: seq.len(), iter: seq.iter().enumerate(), make_deserializer: maker }
236    }
237}
238
239impl<'v, 'de, D, F> de::SeqAccess<'de> for SeqDe<'v, D, F>
240    where D: Deserializer<'de, Error = Error>, F: Fn(&'v Value) -> D,
241{
242    type Error = Error;
243
244    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
245        where T: de::DeserializeSeed<'de>
246    {
247        if let Some((i, item)) = self.iter.next() {
248            // item.map_tag(|metadata| metadata.path.push(self.count.to_string()));
249            self.len -= 1;
250            seed.deserialize((self.make_deserializer)(item))
251                .map_err(|e: Error| e.prefixed(&i.to_string()))
252                .map(Some)
253        } else {
254            Ok(None)
255        }
256    }
257
258    fn size_hint(&self) -> Option<usize> {
259        Some(self.len)
260    }
261}
262
263impl<'de> Deserializer<'de> for &Value {
264    type Error = Error;
265
266    fn deserialize_any<V>(self, v: V) -> Result<V::Value>
267        where V: de::Visitor<'de>
268    {
269        use Value::*;
270        let result = match *self {
271            String(_, ref s) => v.visit_str(s),
272            Char(_, c) => v.visit_char(c),
273            Bool(_, b) => v.visit_bool(b),
274            Num(_, n) => n.deserialize_any(v),
275            Empty(_, e) => e.deserialize_any(v),
276            Dict(_, ref map) => v.visit_map(MapDe::new(map, |v| v)),
277            Array(_, ref seq) => v.visit_seq(SeqDe::new(seq, |v| v)),
278        };
279
280        result.map_err(|e: Error| e.retagged(self.tag()))
281    }
282
283    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
284        where V: Visitor<'de>
285    {
286        if let Value::Empty(t, val) = self {
287            return val.deserialize_any(visitor).map_err(|e: Error| e.retagged(*t));
288        }
289
290        visitor.visit_some(self)
291    }
292
293    fn deserialize_enum<V: Visitor<'de>>(
294        self,
295        _: &'static str,
296        _: &'static [&'static str],
297        v: V,
298    ) -> Result<V::Value> {
299        use serde::de::value::MapAccessDeserializer;
300
301        let result = match self {
302            Value::String(_, s) => v.visit_enum((&**s).into_deserializer()),
303            Value::Dict(_, ref map) => {
304                let map_access = MapDe::new(map, |v| v);
305                v.visit_enum(MapAccessDeserializer::new(map_access))
306            }
307            Value::Num(_, n) if n.to_u32().is_some() => {
308                let tag = n.to_u32().unwrap();
309                v.visit_enum(tag.into_deserializer())
310            }
311            _ => self.deserialize_any(v)
312        };
313
314        result.map_err(|e: Error| e.retagged(self.tag()))
315    }
316
317    fn deserialize_newtype_struct<V: Visitor<'de>>(
318        self,
319        _name: &'static str,
320        visitor: V,
321    ) -> Result<V::Value> {
322        visitor.visit_newtype_struct(self)
323    }
324
325    serde::forward_to_deserialize_any! {
326        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str
327        string seq bytes byte_buf map unit struct
328        ignored_any unit_struct tuple_struct tuple identifier
329    }
330}
331
332macro_rules! int_try {
333    ($n:expr; $o:ty => $t:ty => $($r:tt)*) => (
334        if ($n as $t as $o) == $n { return $($r)*($n as $t); }
335    )
336}
337
338impl<'de> Deserializer<'de> for Num {
339    type Error = Error;
340
341    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
342        where V: de::Visitor<'de>
343    {
344        match self {
345            Num::U8(n) => visitor.visit_u8(n),
346            Num::U16(n) => visitor.visit_u16(n),
347            Num::U32(n) => visitor.visit_u32(n),
348            Num::U64(n) => visitor.visit_u64(n),
349            Num::U128(n) => visitor.visit_u128(n),
350            Num::I8(n) => visitor.visit_i8(n),
351            Num::I16(n) => visitor.visit_i16(n),
352            Num::I32(n) => visitor.visit_i32(n),
353            Num::I64(n) => visitor.visit_i64(n),
354            Num::I128(n) => visitor.visit_i128(n),
355            Num::F32(n) => visitor.visit_f32(n),
356            Num::F64(n) => visitor.visit_f64(n),
357            Num::ISize(n) => {
358                int_try!(n; isize => i8 => visitor.visit_i8);
359                int_try!(n; isize => i16 => visitor.visit_i16);
360                int_try!(n; isize => i32 => visitor.visit_i32);
361                int_try!(n; isize => i64 => visitor.visit_i64);
362                int_try!(n; isize => i128 => visitor.visit_i128);
363                Err(Kind::ISizeOutOfRange(n).into())
364            }
365            Num::USize(n) => {
366                int_try!(n; usize => u8 => visitor.visit_u8);
367                int_try!(n; usize => u16 => visitor.visit_u16);
368                int_try!(n; usize => u32 => visitor.visit_u32);
369                int_try!(n; usize => u64 => visitor.visit_u64);
370                int_try!(n; usize => u128 => visitor.visit_u128);
371                Err(Kind::USizeOutOfRange(n).into())
372            }
373        }
374    }
375
376    serde::forward_to_deserialize_any! {
377        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq enum
378        bytes byte_buf map struct unit newtype_struct
379        ignored_any unit_struct tuple_struct tuple option identifier
380    }
381}
382
383impl<'de> Deserializer<'de> for Empty {
384    type Error = Error;
385
386    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
387        where V: de::Visitor<'de>
388    {
389        match self {
390            Empty::Unit => visitor.visit_unit(),
391            Empty::None => visitor.visit_none(),
392        }
393    }
394
395    serde::forward_to_deserialize_any! {
396        bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq enum
397        bytes byte_buf map struct unit newtype_struct
398        ignored_any unit_struct tuple_struct tuple option identifier
399    }
400}
401
402/// Marker trait for "magic" values. Primarily for use with [`Either`].
403impl Value {
404    const NAME: &'static str = "___figment_value";
405
406    const FIELDS: &'static [&'static str] = &[
407        "___figment_value_id", "___figment_value_value"
408    ];
409
410    fn deserialize_from<'de: 'c, 'c, V: de::Visitor<'de>, I: Interpreter>(
411        de: ConfiguredValueDe<'c, I>,
412        visitor: V
413    ) -> Result<V::Value> {
414        let mut map = Dict::new();
415        map.insert(Self::FIELDS[0].into(), de.value.tag().into());
416        map.insert(Self::FIELDS[1].into(), de.value.clone());
417        visitor.visit_map(MapDe::new(&map, |v| ConfiguredValueDe::<'_, I>::from(de.config, v)))
418    }
419}
420
421#[derive(Debug)]
422struct RawValue(Value);
423
424impl<'de> Deserialize<'de> for RawValue {
425    fn deserialize<D: Deserializer<'de>>(de: D) -> result::Result<Self, D::Error> {
426        de.deserialize_any(ValueVisitor).map(RawValue)
427    }
428}
429
430impl<'de> Deserialize<'de> for Value {
431    fn deserialize<D: Deserializer<'de>>(de: D) -> result::Result<Value, D::Error> {
432        // Total hack to "fingerprint" our deserializer by checking if
433        // human_readable changes, which does for ours but shouldn't for others.
434        let (a, b) = (de.is_human_readable(), de.is_human_readable());
435        if a != b {
436            de.deserialize_struct(Value::NAME, Value::FIELDS, ValueVisitor)
437        } else {
438            de.deserialize_any(ValueVisitor)
439        }
440    }
441}
442
443pub struct ValueVisitor;
444
445macro_rules! visit_fn {
446    ($name:ident: $T:ty => $V:path) => (
447        #[inline]
448        fn $name<E: de::Error>(self, v: $T) -> result::Result<Self::Value, E> {
449            Ok(v.into())
450        }
451    )
452}
453
454impl<'de> Visitor<'de> for ValueVisitor {
455    type Value = Value;
456
457    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
458        f.write_str("any valid figment value")
459    }
460
461    visit_fn!(visit_bool: bool => Value::Bool);
462    visit_fn!(visit_char: char => Value::Char);
463    visit_fn!(visit_str: &str => Value::String);
464    visit_fn!(visit_string: String => Value::String);
465
466    visit_fn!(visit_u8: u8 => Num::U8);
467    visit_fn!(visit_u16: u16 => Num::U16);
468    visit_fn!(visit_u32: u32 => Num::U32);
469    visit_fn!(visit_u64: u64 => Num::U64);
470    visit_fn!(visit_u128: u128 => Num::U128);
471
472    visit_fn!(visit_i8: i8 => Num::I8);
473    visit_fn!(visit_i16: i16 => Num::I16);
474    visit_fn!(visit_i32: i32 => Num::I32);
475    visit_fn!(visit_i64: i64 => Num::I64);
476    visit_fn!(visit_i128: i128 => Num::I128);
477
478    visit_fn!(visit_f32: f32 => Num::F32);
479    visit_fn!(visit_f64: f64 => Num::F64);
480
481    fn visit_seq<A>(self, mut seq: A) -> result::Result<Self::Value, A::Error>
482        where A: SeqAccess<'de>
483    {
484        let mut array: Vec<Value> = Vec::with_capacity(seq.size_hint().unwrap_or(0));
485        while let Some(elem) = seq.next_element()? {
486            array.push(elem);
487        }
488
489        Ok(array.into())
490    }
491
492    fn visit_map<A>(self, mut map: A) -> result::Result<Self::Value, A::Error>
493        where A: MapAccess<'de>
494    {
495        let mut dict = Dict::new();
496        let mut id: Option<Tag> = None;
497        let mut raw_val: Option<RawValue> = None;
498        while let Some(key) = map.next_key()? {
499            if key == Value::FIELDS[0] {
500                id = Some(map.next_value()?);
501            } else if key == Value::FIELDS[1] {
502                raw_val = Some(map.next_value()?);
503            }  else {
504                dict.insert(key, map.next_value()?);
505            }
506        }
507
508        if let Some(mut value) = raw_val {
509            if let Some(id) = id {
510                value.0.map_tag(|t| *t = id);
511            }
512
513            return Ok(value.0);
514        }
515
516        Ok(dict.into())
517    }
518
519    fn visit_enum<A: de::EnumAccess<'de>>(self, data: A) -> result::Result<Self::Value, A::Error> {
520        let (tag, variant) = data.variant::<String>()?;
521        Ok(crate::util::nest(&tag, variant.newtype_variant()?))
522    }
523
524    fn visit_none<E: de::Error>(self) -> result::Result<Self::Value, E> {
525        Ok(Empty::None.into())
526    }
527
528    fn visit_some<D>(self, deserializer: D) -> result::Result<Self::Value, D::Error>
529        where D: Deserializer<'de>,
530    {
531        deserializer.deserialize_any(self)
532    }
533
534    fn visit_unit<E: de::Error>(self) -> result::Result<Self::Value, E> {
535        Ok(Empty::Unit.into())
536    }
537}