1use error::*;
2use serde::de::{Deserialize, Deserializer, Visitor};
3use std::collections::HashMap;
4use std::fmt;
5use std::fmt::Display;
6
7#[derive(Debug, Clone, PartialEq)]
9pub enum ValueKind {
10 Nil,
11 Boolean(bool),
12 Integer(i64),
13 Float(f64),
14 String(String),
15 Table(Table),
16 Array(Array),
17}
18
19pub type Array = Vec<Value>;
20pub type Table = HashMap<String, Value>;
21
22impl Default for ValueKind {
23 fn default() -> Self {
24 ValueKind::Nil
25 }
26}
27
28impl<T> From<Option<T>> for ValueKind
29where
30 T: Into<ValueKind>,
31{
32 fn from(value: Option<T>) -> Self {
33 match value {
34 Some(value) => value.into(),
35 None => ValueKind::Nil,
36 }
37 }
38}
39
40impl From<String> for ValueKind {
41 fn from(value: String) -> Self {
42 ValueKind::String(value)
43 }
44}
45
46impl<'a> From<&'a str> for ValueKind {
47 fn from(value: &'a str) -> Self {
48 ValueKind::String(value.into())
49 }
50}
51
52impl From<i64> for ValueKind {
53 fn from(value: i64) -> Self {
54 ValueKind::Integer(value)
55 }
56}
57
58impl From<f64> for ValueKind {
59 fn from(value: f64) -> Self {
60 ValueKind::Float(value)
61 }
62}
63
64impl From<bool> for ValueKind {
65 fn from(value: bool) -> Self {
66 ValueKind::Boolean(value)
67 }
68}
69
70impl<T> From<HashMap<String, T>> for ValueKind
71where
72 T: Into<Value>,
73{
74 fn from(values: HashMap<String, T>) -> Self {
75 let mut r = HashMap::new();
76
77 for (k, v) in values {
78 r.insert(k.clone(), v.into());
79 }
80
81 ValueKind::Table(r)
82 }
83}
84
85impl<T> From<Vec<T>> for ValueKind
86where
87 T: Into<Value>,
88{
89 fn from(values: Vec<T>) -> Self {
90 let mut l = Vec::new();
91
92 for v in values {
93 l.push(v.into());
94 }
95
96 ValueKind::Array(l)
97 }
98}
99
100impl Display for ValueKind {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 match *self {
103 ValueKind::String(ref value) => write!(f, "{}", value),
104 ValueKind::Boolean(value) => write!(f, "{}", value),
105 ValueKind::Integer(value) => write!(f, "{}", value),
106 ValueKind::Float(value) => write!(f, "{}", value),
107 ValueKind::Nil => write!(f, "nil"),
108
109 ValueKind::Table(ref table) => write!(f, "{:?}", table),
111 ValueKind::Array(ref array) => write!(f, "{:?}", array),
112 }
113 }
114}
115
116#[derive(Default, Debug, Clone, PartialEq)]
118pub struct Value {
119 origin: Option<String>,
136
137 pub kind: ValueKind,
139}
140
141impl Value {
142 pub fn new<V>(origin: Option<&String>, kind: V) -> Self
144 where
145 V: Into<ValueKind>,
146 {
147 Value {
148 origin: origin.cloned(),
149 kind: kind.into(),
150 }
151 }
152
153 pub fn try_into<'de, T: Deserialize<'de>>(self) -> Result<T> {
155 T::deserialize(self)
156 }
157
158 pub fn into_bool(self) -> Result<bool> {
161 match self.kind {
162 ValueKind::Boolean(value) => Ok(value),
163 ValueKind::Integer(value) => Ok(value != 0),
164 ValueKind::Float(value) => Ok(value != 0.0),
165
166 ValueKind::String(ref value) => {
167 match value.to_lowercase().as_ref() {
168 "1" | "true" | "on" | "yes" => Ok(true),
169 "0" | "false" | "off" | "no" => Ok(false),
170
171 s => Err(ConfigError::invalid_type(
173 self.origin.clone(),
174 Unexpected::Str(s.into()),
175 "a boolean",
176 )),
177 }
178 }
179
180 ValueKind::Nil => Err(ConfigError::invalid_type(
182 self.origin,
183 Unexpected::Unit,
184 "a boolean",
185 )),
186 ValueKind::Table(_) => Err(ConfigError::invalid_type(
187 self.origin,
188 Unexpected::Map,
189 "a boolean",
190 )),
191 ValueKind::Array(_) => Err(ConfigError::invalid_type(
192 self.origin,
193 Unexpected::Seq,
194 "a boolean",
195 )),
196 }
197 }
198
199 pub fn into_int(self) -> Result<i64> {
202 match self.kind {
203 ValueKind::Integer(value) => Ok(value),
204
205 ValueKind::String(ref s) => {
206 match s.to_lowercase().as_ref() {
207 "true" | "on" | "yes" => Ok(1),
208 "false" | "off" | "no" => Ok(0),
209 _ => {
210 s.parse().map_err(|_| {
211 ConfigError::invalid_type(
213 self.origin.clone(),
214 Unexpected::Str(s.clone()),
215 "an integer",
216 )
217 })
218 }
219 }
220 }
221
222 ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
223 ValueKind::Float(value) => Ok(value.round() as i64),
224
225 ValueKind::Nil => Err(ConfigError::invalid_type(
227 self.origin,
228 Unexpected::Unit,
229 "an integer",
230 )),
231 ValueKind::Table(_) => Err(ConfigError::invalid_type(
232 self.origin,
233 Unexpected::Map,
234 "an integer",
235 )),
236 ValueKind::Array(_) => Err(ConfigError::invalid_type(
237 self.origin,
238 Unexpected::Seq,
239 "an integer",
240 )),
241 }
242 }
243
244 pub fn into_float(self) -> Result<f64> {
247 match self.kind {
248 ValueKind::Float(value) => Ok(value),
249
250 ValueKind::String(ref s) => {
251 match s.to_lowercase().as_ref() {
252 "true" | "on" | "yes" => Ok(1.0),
253 "false" | "off" | "no" => Ok(0.0),
254 _ => {
255 s.parse().map_err(|_| {
256 ConfigError::invalid_type(
258 self.origin.clone(),
259 Unexpected::Str(s.clone()),
260 "a floating point",
261 )
262 })
263 }
264 }
265 }
266
267 ValueKind::Integer(value) => Ok(value as f64),
268 ValueKind::Boolean(value) => Ok(if value { 1.0 } else { 0.0 }),
269
270 ValueKind::Nil => Err(ConfigError::invalid_type(
272 self.origin,
273 Unexpected::Unit,
274 "a floating point",
275 )),
276 ValueKind::Table(_) => Err(ConfigError::invalid_type(
277 self.origin,
278 Unexpected::Map,
279 "a floating point",
280 )),
281 ValueKind::Array(_) => Err(ConfigError::invalid_type(
282 self.origin,
283 Unexpected::Seq,
284 "a floating point",
285 )),
286 }
287 }
288
289 pub fn into_str(self) -> Result<String> {
292 match self.kind {
293 ValueKind::String(value) => Ok(value),
294
295 ValueKind::Boolean(value) => Ok(value.to_string()),
296 ValueKind::Integer(value) => Ok(value.to_string()),
297 ValueKind::Float(value) => Ok(value.to_string()),
298
299 ValueKind::Nil => Err(ConfigError::invalid_type(
301 self.origin,
302 Unexpected::Unit,
303 "a string",
304 )),
305 ValueKind::Table(_) => Err(ConfigError::invalid_type(
306 self.origin,
307 Unexpected::Map,
308 "a string",
309 )),
310 ValueKind::Array(_) => Err(ConfigError::invalid_type(
311 self.origin,
312 Unexpected::Seq,
313 "a string",
314 )),
315 }
316 }
317
318 pub fn into_array(self) -> Result<Vec<Value>> {
321 match self.kind {
322 ValueKind::Array(value) => Ok(value),
323
324 ValueKind::Float(value) => Err(ConfigError::invalid_type(
326 self.origin,
327 Unexpected::Float(value),
328 "an array",
329 )),
330 ValueKind::String(value) => Err(ConfigError::invalid_type(
331 self.origin,
332 Unexpected::Str(value),
333 "an array",
334 )),
335 ValueKind::Integer(value) => Err(ConfigError::invalid_type(
336 self.origin,
337 Unexpected::Integer(value),
338 "an array",
339 )),
340 ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
341 self.origin,
342 Unexpected::Bool(value),
343 "an array",
344 )),
345 ValueKind::Nil => Err(ConfigError::invalid_type(
346 self.origin,
347 Unexpected::Unit,
348 "an array",
349 )),
350 ValueKind::Table(_) => Err(ConfigError::invalid_type(
351 self.origin,
352 Unexpected::Map,
353 "an array",
354 )),
355 }
356 }
357
358 pub fn into_table(self) -> Result<HashMap<String, Value>> {
361 match self.kind {
362 ValueKind::Table(value) => Ok(value),
363
364 ValueKind::Float(value) => Err(ConfigError::invalid_type(
366 self.origin,
367 Unexpected::Float(value),
368 "a map",
369 )),
370 ValueKind::String(value) => Err(ConfigError::invalid_type(
371 self.origin,
372 Unexpected::Str(value),
373 "a map",
374 )),
375 ValueKind::Integer(value) => Err(ConfigError::invalid_type(
376 self.origin,
377 Unexpected::Integer(value),
378 "a map",
379 )),
380 ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
381 self.origin,
382 Unexpected::Bool(value),
383 "a map",
384 )),
385 ValueKind::Nil => Err(ConfigError::invalid_type(
386 self.origin,
387 Unexpected::Unit,
388 "a map",
389 )),
390 ValueKind::Array(_) => Err(ConfigError::invalid_type(
391 self.origin,
392 Unexpected::Seq,
393 "a map",
394 )),
395 }
396 }
397}
398
399impl<'de> Deserialize<'de> for Value {
400 #[inline]
401 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Value, D::Error>
402 where
403 D: Deserializer<'de>,
404 {
405 struct ValueVisitor;
406
407 impl<'de> Visitor<'de> for ValueVisitor {
408 type Value = Value;
409
410 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
411 formatter.write_str("any valid configuration value")
412 }
413
414 #[inline]
415 fn visit_bool<E>(self, value: bool) -> ::std::result::Result<Value, E> {
416 Ok(value.into())
417 }
418
419 #[inline]
420 fn visit_i8<E>(self, value: i8) -> ::std::result::Result<Value, E> {
421 Ok((value as i64).into())
422 }
423
424 #[inline]
425 fn visit_i16<E>(self, value: i16) -> ::std::result::Result<Value, E> {
426 Ok((value as i64).into())
427 }
428
429 #[inline]
430 fn visit_i32<E>(self, value: i32) -> ::std::result::Result<Value, E> {
431 Ok((value as i64).into())
432 }
433
434 #[inline]
435 fn visit_i64<E>(self, value: i64) -> ::std::result::Result<Value, E> {
436 Ok(value.into())
437 }
438
439 #[inline]
440 fn visit_u8<E>(self, value: u8) -> ::std::result::Result<Value, E> {
441 Ok((value as i64).into())
442 }
443
444 #[inline]
445 fn visit_u16<E>(self, value: u16) -> ::std::result::Result<Value, E> {
446 Ok((value as i64).into())
447 }
448
449 #[inline]
450 fn visit_u32<E>(self, value: u32) -> ::std::result::Result<Value, E> {
451 Ok((value as i64).into())
452 }
453
454 #[inline]
455 fn visit_u64<E>(self, value: u64) -> ::std::result::Result<Value, E> {
456 Ok((value as i64).into())
458 }
459
460 #[inline]
461 fn visit_f64<E>(self, value: f64) -> ::std::result::Result<Value, E> {
462 Ok(value.into())
463 }
464
465 #[inline]
466 fn visit_str<E>(self, value: &str) -> ::std::result::Result<Value, E>
467 where
468 E: ::serde::de::Error,
469 {
470 self.visit_string(String::from(value))
471 }
472
473 #[inline]
474 fn visit_string<E>(self, value: String) -> ::std::result::Result<Value, E> {
475 Ok(value.into())
476 }
477
478 #[inline]
479 fn visit_none<E>(self) -> ::std::result::Result<Value, E> {
480 Ok(Value::new(None, ValueKind::Nil))
481 }
482
483 #[inline]
484 fn visit_some<D>(self, deserializer: D) -> ::std::result::Result<Value, D::Error>
485 where
486 D: Deserializer<'de>,
487 {
488 Deserialize::deserialize(deserializer)
489 }
490
491 #[inline]
492 fn visit_unit<E>(self) -> ::std::result::Result<Value, E> {
493 Ok(Value::new(None, ValueKind::Nil))
494 }
495
496 #[inline]
497 fn visit_seq<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error>
498 where
499 V: ::serde::de::SeqAccess<'de>,
500 {
501 let mut vec = Array::new();
502
503 while let Some(elem) = visitor.next_element()? {
504 vec.push(elem);
505 }
506
507 Ok(vec.into())
508 }
509
510 fn visit_map<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error>
511 where
512 V: ::serde::de::MapAccess<'de>,
513 {
514 let mut values = Table::new();
515
516 while let Some((key, value)) = visitor.next_entry()? {
517 values.insert(key, value);
518 }
519
520 Ok(values.into())
521 }
522 }
523
524 deserializer.deserialize_any(ValueVisitor)
525 }
526}
527
528impl<T> From<T> for Value
529where
530 T: Into<ValueKind>,
531{
532 fn from(value: T) -> Self {
533 Value {
534 origin: None,
535 kind: value.into(),
536 }
537 }
538}
539
540impl Display for Value {
541 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
542 write!(f, "{}", self.kind)
543 }
544}