1 use std::convert::TryInto;
2 use std::fmt;
3 use std::fmt::Display;
4 
5 use serde::de::{Deserialize, Deserializer, Visitor};
6 
7 use crate::error::{ConfigError, Result, Unexpected};
8 use crate::map::Map;
9 
10 /// Underlying kind of the configuration value.
11 ///
12 /// Standard operations on a `Value` by users of this crate do not require
13 /// knowledge of `ValueKind`. Introspection of underlying kind is only required
14 /// when the configuration values are unstructured or do not have known types.
15 #[derive(Debug, Clone, PartialEq)]
16 pub enum ValueKind {
17     Nil,
18     Boolean(bool),
19     I64(i64),
20     I128(i128),
21     U64(u64),
22     U128(u128),
23     Float(f64),
24     String(String),
25     Table(Table),
26     Array(Array),
27 }
28 
29 pub type Array = Vec<Value>;
30 pub type Table = Map<String, Value>;
31 
32 impl Default for ValueKind {
default() -> Self33     fn default() -> Self {
34         Self::Nil
35     }
36 }
37 
38 impl<T> From<Option<T>> for ValueKind
39 where
40     T: Into<Self>,
41 {
from(value: Option<T>) -> Self42     fn from(value: Option<T>) -> Self {
43         match value {
44             Some(value) => value.into(),
45             None => Self::Nil,
46         }
47     }
48 }
49 
50 impl From<String> for ValueKind {
from(value: String) -> Self51     fn from(value: String) -> Self {
52         Self::String(value)
53     }
54 }
55 
56 impl<'a> From<&'a str> for ValueKind {
from(value: &'a str) -> Self57     fn from(value: &'a str) -> Self {
58         Self::String(value.into())
59     }
60 }
61 
62 impl From<i8> for ValueKind {
from(value: i8) -> Self63     fn from(value: i8) -> Self {
64         Self::I64(value.into())
65     }
66 }
67 
68 impl From<i16> for ValueKind {
from(value: i16) -> Self69     fn from(value: i16) -> Self {
70         Self::I64(value.into())
71     }
72 }
73 
74 impl From<i32> for ValueKind {
from(value: i32) -> Self75     fn from(value: i32) -> Self {
76         Self::I64(value.into())
77     }
78 }
79 
80 impl From<i64> for ValueKind {
from(value: i64) -> Self81     fn from(value: i64) -> Self {
82         Self::I64(value)
83     }
84 }
85 
86 impl From<i128> for ValueKind {
from(value: i128) -> Self87     fn from(value: i128) -> Self {
88         Self::I128(value)
89     }
90 }
91 
92 impl From<u8> for ValueKind {
from(value: u8) -> Self93     fn from(value: u8) -> Self {
94         Self::U64(value.into())
95     }
96 }
97 
98 impl From<u16> for ValueKind {
from(value: u16) -> Self99     fn from(value: u16) -> Self {
100         Self::U64(value.into())
101     }
102 }
103 
104 impl From<u32> for ValueKind {
from(value: u32) -> Self105     fn from(value: u32) -> Self {
106         Self::U64(value.into())
107     }
108 }
109 
110 impl From<u64> for ValueKind {
from(value: u64) -> Self111     fn from(value: u64) -> Self {
112         Self::U64(value)
113     }
114 }
115 
116 impl From<u128> for ValueKind {
from(value: u128) -> Self117     fn from(value: u128) -> Self {
118         Self::U128(value)
119     }
120 }
121 
122 impl From<f64> for ValueKind {
from(value: f64) -> Self123     fn from(value: f64) -> Self {
124         Self::Float(value)
125     }
126 }
127 
128 impl From<bool> for ValueKind {
from(value: bool) -> Self129     fn from(value: bool) -> Self {
130         Self::Boolean(value)
131     }
132 }
133 
134 impl<T> From<Map<String, T>> for ValueKind
135 where
136     T: Into<Value>,
137 {
from(values: Map<String, T>) -> Self138     fn from(values: Map<String, T>) -> Self {
139         let t = values.into_iter().map(|(k, v)| (k, v.into())).collect();
140         Self::Table(t)
141     }
142 }
143 
144 impl<T> From<Vec<T>> for ValueKind
145 where
146     T: Into<Value>,
147 {
from(values: Vec<T>) -> Self148     fn from(values: Vec<T>) -> Self {
149         Self::Array(values.into_iter().map(T::into).collect())
150     }
151 }
152 
153 impl Display for ValueKind {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result154     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155         match *self {
156             Self::String(ref value) => write!(f, "{}", value),
157             Self::Boolean(value) => write!(f, "{}", value),
158             Self::I64(value) => write!(f, "{}", value),
159             Self::I128(value) => write!(f, "{}", value),
160             Self::U64(value) => write!(f, "{}", value),
161             Self::U128(value) => write!(f, "{}", value),
162             Self::Float(value) => write!(f, "{}", value),
163             Self::Nil => write!(f, "nil"),
164             Self::Table(ref table) => write!(f, "{{ {} }}", {
165                 table
166                     .iter()
167                     .map(|(k, v)| format!("{} => {}, ", k, v))
168                     .collect::<String>()
169             }),
170             Self::Array(ref array) => write!(f, "{:?}", {
171                 array.iter().map(|e| format!("{}, ", e)).collect::<String>()
172             }),
173         }
174     }
175 }
176 
177 /// A configuration value.
178 #[derive(Default, Debug, Clone, PartialEq)]
179 pub struct Value {
180     /// A description of the original location of the value.
181     ///
182     /// A Value originating from a File might contain:
183     /// ```text
184     /// Settings.toml
185     /// ```
186     ///
187     /// A Value originating from the environment would contain:
188     /// ```text
189     /// the envrionment
190     /// ```
191     ///
192     /// A Value originating from a remote source might contain:
193     /// ```text
194     /// etcd+http://127.0.0.1:2379
195     /// ```
196     origin: Option<String>,
197 
198     /// Underlying kind of the configuration value.
199     pub kind: ValueKind,
200 }
201 
202 impl Value {
203     /// Create a new value instance that will remember its source uri.
new<V>(origin: Option<&String>, kind: V) -> Self where V: Into<ValueKind>,204     pub fn new<V>(origin: Option<&String>, kind: V) -> Self
205     where
206         V: Into<ValueKind>,
207     {
208         Self {
209             origin: origin.cloned(),
210             kind: kind.into(),
211         }
212     }
213 
214     /// Attempt to deserialize this value into the requested type.
try_deserialize<'de, T: Deserialize<'de>>(self) -> Result<T>215     pub fn try_deserialize<'de, T: Deserialize<'de>>(self) -> Result<T> {
216         T::deserialize(self)
217     }
218 
219     /// Returns `self` as a bool, if possible.
220     // FIXME: Should this not be `try_into_*` ?
into_bool(self) -> Result<bool>221     pub fn into_bool(self) -> Result<bool> {
222         match self.kind {
223             ValueKind::Boolean(value) => Ok(value),
224             ValueKind::I64(value) => Ok(value != 0),
225             ValueKind::I128(value) => Ok(value != 0),
226             ValueKind::U64(value) => Ok(value != 0),
227             ValueKind::U128(value) => Ok(value != 0),
228             ValueKind::Float(value) => Ok(value != 0.0),
229 
230             ValueKind::String(ref value) => {
231                 match value.to_lowercase().as_ref() {
232                     "1" | "true" | "on" | "yes" => Ok(true),
233                     "0" | "false" | "off" | "no" => Ok(false),
234 
235                     // Unexpected string value
236                     s => Err(ConfigError::invalid_type(
237                         self.origin.clone(),
238                         Unexpected::Str(s.into()),
239                         "a boolean",
240                     )),
241                 }
242             }
243 
244             // Unexpected type
245             ValueKind::Nil => Err(ConfigError::invalid_type(
246                 self.origin,
247                 Unexpected::Unit,
248                 "a boolean",
249             )),
250             ValueKind::Table(_) => Err(ConfigError::invalid_type(
251                 self.origin,
252                 Unexpected::Map,
253                 "a boolean",
254             )),
255             ValueKind::Array(_) => Err(ConfigError::invalid_type(
256                 self.origin,
257                 Unexpected::Seq,
258                 "a boolean",
259             )),
260         }
261     }
262 
263     /// Returns `self` into an i64, if possible.
264     // FIXME: Should this not be `try_into_*` ?
into_int(self) -> Result<i64>265     pub fn into_int(self) -> Result<i64> {
266         match self.kind {
267             ValueKind::I64(value) => Ok(value),
268             ValueKind::I128(value) => value.try_into().map_err(|_| {
269                 ConfigError::invalid_type(
270                     self.origin,
271                     Unexpected::I128(value),
272                     "an signed 64 bit or less integer",
273                 )
274             }),
275             ValueKind::U64(value) => value.try_into().map_err(|_| {
276                 ConfigError::invalid_type(
277                     self.origin,
278                     Unexpected::U64(value),
279                     "an signed 64 bit or less integer",
280                 )
281             }),
282             ValueKind::U128(value) => value.try_into().map_err(|_| {
283                 ConfigError::invalid_type(
284                     self.origin,
285                     Unexpected::U128(value),
286                     "an signed 64 bit or less integer",
287                 )
288             }),
289 
290             ValueKind::String(ref s) => {
291                 match s.to_lowercase().as_ref() {
292                     "true" | "on" | "yes" => Ok(1),
293                     "false" | "off" | "no" => Ok(0),
294                     _ => {
295                         s.parse().map_err(|_| {
296                             // Unexpected string
297                             ConfigError::invalid_type(
298                                 self.origin.clone(),
299                                 Unexpected::Str(s.clone()),
300                                 "an integer",
301                             )
302                         })
303                     }
304                 }
305             }
306 
307             ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
308             ValueKind::Float(value) => Ok(value.round() as i64),
309 
310             // Unexpected type
311             ValueKind::Nil => Err(ConfigError::invalid_type(
312                 self.origin,
313                 Unexpected::Unit,
314                 "an integer",
315             )),
316             ValueKind::Table(_) => Err(ConfigError::invalid_type(
317                 self.origin,
318                 Unexpected::Map,
319                 "an integer",
320             )),
321             ValueKind::Array(_) => Err(ConfigError::invalid_type(
322                 self.origin,
323                 Unexpected::Seq,
324                 "an integer",
325             )),
326         }
327     }
328 
329     /// Returns `self` into an i128, if possible.
into_int128(self) -> Result<i128>330     pub fn into_int128(self) -> Result<i128> {
331         match self.kind {
332             ValueKind::I64(value) => Ok(value.into()),
333             ValueKind::I128(value) => Ok(value),
334             ValueKind::U64(value) => Ok(value.into()),
335             ValueKind::U128(value) => value.try_into().map_err(|_| {
336                 ConfigError::invalid_type(
337                     self.origin,
338                     Unexpected::U128(value),
339                     "an signed 128 bit integer",
340                 )
341             }),
342 
343             ValueKind::String(ref s) => {
344                 match s.to_lowercase().as_ref() {
345                     "true" | "on" | "yes" => Ok(1),
346                     "false" | "off" | "no" => Ok(0),
347                     _ => {
348                         s.parse().map_err(|_| {
349                             // Unexpected string
350                             ConfigError::invalid_type(
351                                 self.origin.clone(),
352                                 Unexpected::Str(s.clone()),
353                                 "an integer",
354                             )
355                         })
356                     }
357                 }
358             }
359 
360             ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
361             ValueKind::Float(value) => Ok(value.round() as i128),
362 
363             // Unexpected type
364             ValueKind::Nil => Err(ConfigError::invalid_type(
365                 self.origin,
366                 Unexpected::Unit,
367                 "an integer",
368             )),
369             ValueKind::Table(_) => Err(ConfigError::invalid_type(
370                 self.origin,
371                 Unexpected::Map,
372                 "an integer",
373             )),
374             ValueKind::Array(_) => Err(ConfigError::invalid_type(
375                 self.origin,
376                 Unexpected::Seq,
377                 "an integer",
378             )),
379         }
380     }
381 
382     /// Returns `self` into an u64, if possible.
383     // FIXME: Should this not be `try_into_*` ?
into_uint(self) -> Result<u64>384     pub fn into_uint(self) -> Result<u64> {
385         match self.kind {
386             ValueKind::U64(value) => Ok(value),
387             ValueKind::U128(value) => value.try_into().map_err(|_| {
388                 ConfigError::invalid_type(
389                     self.origin,
390                     Unexpected::U128(value),
391                     "an unsigned 64 bit or less integer",
392                 )
393             }),
394             ValueKind::I64(value) => value.try_into().map_err(|_| {
395                 ConfigError::invalid_type(
396                     self.origin,
397                     Unexpected::I64(value),
398                     "an unsigned 64 bit or less integer",
399                 )
400             }),
401             ValueKind::I128(value) => value.try_into().map_err(|_| {
402                 ConfigError::invalid_type(
403                     self.origin,
404                     Unexpected::I128(value),
405                     "an unsigned 64 bit or less integer",
406                 )
407             }),
408 
409             ValueKind::String(ref s) => {
410                 match s.to_lowercase().as_ref() {
411                     "true" | "on" | "yes" => Ok(1),
412                     "false" | "off" | "no" => Ok(0),
413                     _ => {
414                         s.parse().map_err(|_| {
415                             // Unexpected string
416                             ConfigError::invalid_type(
417                                 self.origin.clone(),
418                                 Unexpected::Str(s.clone()),
419                                 "an integer",
420                             )
421                         })
422                     }
423                 }
424             }
425 
426             ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
427             ValueKind::Float(value) => Ok(value.round() as u64),
428 
429             // Unexpected type
430             ValueKind::Nil => Err(ConfigError::invalid_type(
431                 self.origin,
432                 Unexpected::Unit,
433                 "an integer",
434             )),
435             ValueKind::Table(_) => Err(ConfigError::invalid_type(
436                 self.origin,
437                 Unexpected::Map,
438                 "an integer",
439             )),
440             ValueKind::Array(_) => Err(ConfigError::invalid_type(
441                 self.origin,
442                 Unexpected::Seq,
443                 "an integer",
444             )),
445         }
446     }
447 
448     /// Returns `self` into an u128, if possible.
into_uint128(self) -> Result<u128>449     pub fn into_uint128(self) -> Result<u128> {
450         match self.kind {
451             ValueKind::U64(value) => Ok(value.into()),
452             ValueKind::U128(value) => Ok(value),
453             ValueKind::I64(value) => value.try_into().map_err(|_| {
454                 ConfigError::invalid_type(
455                     self.origin,
456                     Unexpected::I64(value),
457                     "an unsigned 128 bit or less integer",
458                 )
459             }),
460             ValueKind::I128(value) => value.try_into().map_err(|_| {
461                 ConfigError::invalid_type(
462                     self.origin,
463                     Unexpected::I128(value),
464                     "an unsigned 128 bit or less integer",
465                 )
466             }),
467 
468             ValueKind::String(ref s) => {
469                 match s.to_lowercase().as_ref() {
470                     "true" | "on" | "yes" => Ok(1),
471                     "false" | "off" | "no" => Ok(0),
472                     _ => {
473                         s.parse().map_err(|_| {
474                             // Unexpected string
475                             ConfigError::invalid_type(
476                                 self.origin.clone(),
477                                 Unexpected::Str(s.clone()),
478                                 "an integer",
479                             )
480                         })
481                     }
482                 }
483             }
484 
485             ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
486             ValueKind::Float(value) => Ok(value.round() as u128),
487 
488             // Unexpected type
489             ValueKind::Nil => Err(ConfigError::invalid_type(
490                 self.origin,
491                 Unexpected::Unit,
492                 "an integer",
493             )),
494             ValueKind::Table(_) => Err(ConfigError::invalid_type(
495                 self.origin,
496                 Unexpected::Map,
497                 "an integer",
498             )),
499             ValueKind::Array(_) => Err(ConfigError::invalid_type(
500                 self.origin,
501                 Unexpected::Seq,
502                 "an integer",
503             )),
504         }
505     }
506 
507     /// Returns `self` into a f64, if possible.
508     // FIXME: Should this not be `try_into_*` ?
into_float(self) -> Result<f64>509     pub fn into_float(self) -> Result<f64> {
510         match self.kind {
511             ValueKind::Float(value) => Ok(value),
512 
513             ValueKind::String(ref s) => {
514                 match s.to_lowercase().as_ref() {
515                     "true" | "on" | "yes" => Ok(1.0),
516                     "false" | "off" | "no" => Ok(0.0),
517                     _ => {
518                         s.parse().map_err(|_| {
519                             // Unexpected string
520                             ConfigError::invalid_type(
521                                 self.origin.clone(),
522                                 Unexpected::Str(s.clone()),
523                                 "a floating point",
524                             )
525                         })
526                     }
527                 }
528             }
529 
530             ValueKind::I64(value) => Ok(value as f64),
531             ValueKind::I128(value) => Ok(value as f64),
532             ValueKind::U64(value) => Ok(value as f64),
533             ValueKind::U128(value) => Ok(value as f64),
534             ValueKind::Boolean(value) => Ok(if value { 1.0 } else { 0.0 }),
535 
536             // Unexpected type
537             ValueKind::Nil => Err(ConfigError::invalid_type(
538                 self.origin,
539                 Unexpected::Unit,
540                 "a floating point",
541             )),
542             ValueKind::Table(_) => Err(ConfigError::invalid_type(
543                 self.origin,
544                 Unexpected::Map,
545                 "a floating point",
546             )),
547             ValueKind::Array(_) => Err(ConfigError::invalid_type(
548                 self.origin,
549                 Unexpected::Seq,
550                 "a floating point",
551             )),
552         }
553     }
554 
555     /// Returns `self` into a string, if possible.
556     // FIXME: Should this not be `try_into_*` ?
into_string(self) -> Result<String>557     pub fn into_string(self) -> Result<String> {
558         match self.kind {
559             ValueKind::String(value) => Ok(value),
560 
561             ValueKind::Boolean(value) => Ok(value.to_string()),
562             ValueKind::I64(value) => Ok(value.to_string()),
563             ValueKind::I128(value) => Ok(value.to_string()),
564             ValueKind::U64(value) => Ok(value.to_string()),
565             ValueKind::U128(value) => Ok(value.to_string()),
566             ValueKind::Float(value) => Ok(value.to_string()),
567 
568             // Cannot convert
569             ValueKind::Nil => Err(ConfigError::invalid_type(
570                 self.origin,
571                 Unexpected::Unit,
572                 "a string",
573             )),
574             ValueKind::Table(_) => Err(ConfigError::invalid_type(
575                 self.origin,
576                 Unexpected::Map,
577                 "a string",
578             )),
579             ValueKind::Array(_) => Err(ConfigError::invalid_type(
580                 self.origin,
581                 Unexpected::Seq,
582                 "a string",
583             )),
584         }
585     }
586 
587     /// Returns `self` into an array, if possible
588     // FIXME: Should this not be `try_into_*` ?
into_array(self) -> Result<Vec<Self>>589     pub fn into_array(self) -> Result<Vec<Self>> {
590         match self.kind {
591             ValueKind::Array(value) => Ok(value),
592 
593             // Cannot convert
594             ValueKind::Float(value) => Err(ConfigError::invalid_type(
595                 self.origin,
596                 Unexpected::Float(value),
597                 "an array",
598             )),
599             ValueKind::String(value) => Err(ConfigError::invalid_type(
600                 self.origin,
601                 Unexpected::Str(value),
602                 "an array",
603             )),
604             ValueKind::I64(value) => Err(ConfigError::invalid_type(
605                 self.origin,
606                 Unexpected::I64(value),
607                 "an array",
608             )),
609             ValueKind::I128(value) => Err(ConfigError::invalid_type(
610                 self.origin,
611                 Unexpected::I128(value),
612                 "an array",
613             )),
614             ValueKind::U64(value) => Err(ConfigError::invalid_type(
615                 self.origin,
616                 Unexpected::U64(value),
617                 "an array",
618             )),
619             ValueKind::U128(value) => Err(ConfigError::invalid_type(
620                 self.origin,
621                 Unexpected::U128(value),
622                 "an array",
623             )),
624             ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
625                 self.origin,
626                 Unexpected::Bool(value),
627                 "an array",
628             )),
629             ValueKind::Nil => Err(ConfigError::invalid_type(
630                 self.origin,
631                 Unexpected::Unit,
632                 "an array",
633             )),
634             ValueKind::Table(_) => Err(ConfigError::invalid_type(
635                 self.origin,
636                 Unexpected::Map,
637                 "an array",
638             )),
639         }
640     }
641 
642     /// If the `Value` is a Table, returns the associated Map.
643     // FIXME: Should this not be `try_into_*` ?
into_table(self) -> Result<Map<String, Self>>644     pub fn into_table(self) -> Result<Map<String, Self>> {
645         match self.kind {
646             ValueKind::Table(value) => Ok(value),
647 
648             // Cannot convert
649             ValueKind::Float(value) => Err(ConfigError::invalid_type(
650                 self.origin,
651                 Unexpected::Float(value),
652                 "a map",
653             )),
654             ValueKind::String(value) => Err(ConfigError::invalid_type(
655                 self.origin,
656                 Unexpected::Str(value),
657                 "a map",
658             )),
659             ValueKind::I64(value) => Err(ConfigError::invalid_type(
660                 self.origin,
661                 Unexpected::I64(value),
662                 "a map",
663             )),
664             ValueKind::I128(value) => Err(ConfigError::invalid_type(
665                 self.origin,
666                 Unexpected::I128(value),
667                 "a map",
668             )),
669             ValueKind::U64(value) => Err(ConfigError::invalid_type(
670                 self.origin,
671                 Unexpected::U64(value),
672                 "a map",
673             )),
674             ValueKind::U128(value) => Err(ConfigError::invalid_type(
675                 self.origin,
676                 Unexpected::U128(value),
677                 "a map",
678             )),
679             ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
680                 self.origin,
681                 Unexpected::Bool(value),
682                 "a map",
683             )),
684             ValueKind::Nil => Err(ConfigError::invalid_type(
685                 self.origin,
686                 Unexpected::Unit,
687                 "a map",
688             )),
689             ValueKind::Array(_) => Err(ConfigError::invalid_type(
690                 self.origin,
691                 Unexpected::Seq,
692                 "a map",
693             )),
694         }
695     }
696 }
697 
698 impl<'de> Deserialize<'de> for Value {
699     #[inline]
deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where D: Deserializer<'de>,700     fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
701     where
702         D: Deserializer<'de>,
703     {
704         struct ValueVisitor;
705 
706         impl<'de> Visitor<'de> for ValueVisitor {
707             type Value = Value;
708 
709             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
710                 formatter.write_str("any valid configuration value")
711             }
712 
713             #[inline]
714             fn visit_bool<E>(self, value: bool) -> ::std::result::Result<Value, E> {
715                 Ok(value.into())
716             }
717 
718             #[inline]
719             fn visit_i8<E>(self, value: i8) -> ::std::result::Result<Value, E> {
720                 Ok((i64::from(value)).into())
721             }
722 
723             #[inline]
724             fn visit_i16<E>(self, value: i16) -> ::std::result::Result<Value, E> {
725                 Ok((i64::from(value)).into())
726             }
727 
728             #[inline]
729             fn visit_i32<E>(self, value: i32) -> ::std::result::Result<Value, E> {
730                 Ok((i64::from(value)).into())
731             }
732 
733             #[inline]
734             fn visit_i64<E>(self, value: i64) -> ::std::result::Result<Value, E> {
735                 Ok(value.into())
736             }
737 
738             #[inline]
739             fn visit_i128<E>(self, value: i128) -> ::std::result::Result<Value, E> {
740                 Ok(value.into())
741             }
742 
743             #[inline]
744             fn visit_u8<E>(self, value: u8) -> ::std::result::Result<Value, E> {
745                 Ok((i64::from(value)).into())
746             }
747 
748             #[inline]
749             fn visit_u16<E>(self, value: u16) -> ::std::result::Result<Value, E> {
750                 Ok((i64::from(value)).into())
751             }
752 
753             #[inline]
754             fn visit_u32<E>(self, value: u32) -> ::std::result::Result<Value, E> {
755                 Ok((i64::from(value)).into())
756             }
757 
758             #[inline]
759             fn visit_u64<E>(self, value: u64) -> ::std::result::Result<Value, E> {
760                 // FIXME: This is bad
761                 Ok((value as i64).into())
762             }
763 
764             #[inline]
765             fn visit_u128<E>(self, value: u128) -> ::std::result::Result<Value, E> {
766                 // FIXME: This is bad
767                 Ok((value as i128).into())
768             }
769 
770             #[inline]
771             fn visit_f64<E>(self, value: f64) -> ::std::result::Result<Value, E> {
772                 Ok(value.into())
773             }
774 
775             #[inline]
776             fn visit_str<E>(self, value: &str) -> ::std::result::Result<Value, E>
777             where
778                 E: ::serde::de::Error,
779             {
780                 self.visit_string(String::from(value))
781             }
782 
783             #[inline]
784             fn visit_string<E>(self, value: String) -> ::std::result::Result<Value, E> {
785                 Ok(value.into())
786             }
787 
788             #[inline]
789             fn visit_none<E>(self) -> ::std::result::Result<Value, E> {
790                 Ok(Value::new(None, ValueKind::Nil))
791             }
792 
793             #[inline]
794             fn visit_some<D>(self, deserializer: D) -> ::std::result::Result<Value, D::Error>
795             where
796                 D: Deserializer<'de>,
797             {
798                 Deserialize::deserialize(deserializer)
799             }
800 
801             #[inline]
802             fn visit_unit<E>(self) -> ::std::result::Result<Value, E> {
803                 Ok(Value::new(None, ValueKind::Nil))
804             }
805 
806             #[inline]
807             fn visit_seq<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error>
808             where
809                 V: ::serde::de::SeqAccess<'de>,
810             {
811                 let mut vec = Array::new();
812 
813                 while let Some(elem) = visitor.next_element()? {
814                     vec.push(elem);
815                 }
816 
817                 Ok(vec.into())
818             }
819 
820             fn visit_map<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error>
821             where
822                 V: ::serde::de::MapAccess<'de>,
823             {
824                 let mut values = Table::new();
825 
826                 while let Some((key, value)) = visitor.next_entry()? {
827                     values.insert(key, value);
828                 }
829 
830                 Ok(values.into())
831             }
832         }
833 
834         deserializer.deserialize_any(ValueVisitor)
835     }
836 }
837 
838 impl<T> From<T> for Value
839 where
840     T: Into<ValueKind>,
841 {
from(value: T) -> Self842     fn from(value: T) -> Self {
843         Self {
844             origin: None,
845             kind: value.into(),
846         }
847     }
848 }
849 
850 impl Display for Value {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result851     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
852         write!(f, "{}", self.kind)
853     }
854 }
855 
856 #[cfg(test)]
857 mod tests {
858     use super::ValueKind;
859     use crate::Config;
860     use crate::File;
861     use crate::FileFormat;
862 
863     #[test]
test_i64()864     fn test_i64() {
865         let c = Config::builder()
866             .add_source(File::new("tests/types/i64.toml", FileFormat::Toml))
867             .build()
868             .unwrap();
869 
870         assert!(std::matches!(c.cache.kind, ValueKind::Table(_)));
871         let v = match c.cache.kind {
872             ValueKind::Table(t) => t,
873             _ => unreachable!(),
874         };
875 
876         let value = v.get("value").unwrap();
877         assert!(
878             std::matches!(value.kind, ValueKind::I64(120)),
879             "Is not a i64(120): {:?}",
880             value.kind
881         );
882     }
883 }
884