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
56macro_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 _ => 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 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
402impl 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 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}