1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

use scl::Value as SclValue;
use serde_json::{self, Value};
use serde::de::DeserializeOwned;
use std::path::Path;
use crate::{
    Result,
    error::Error
};

pub struct Conf;

impl Conf {
    pub fn load_file<P, T>(path: P) -> Result<T>
        where P: AsRef<Path>,
              T: DeserializeOwned
    {
        let config = scl::parse_file(path)?;
        serde_json::from_value(Conf::from(SclValue::Dict(config))).map_err(Error::from)
    }

    fn from(val: SclValue) -> serde_json::Value {
        match val {
            SclValue::Boolean(b) => Value::Bool(b),
            SclValue::Integer(i) => serde_json::to_value(i).unwrap_or_default(),
            SclValue::Float(f) => serde_json::to_value(f).unwrap_or_default(),
            SclValue::String(s) => Value::String(s),
            SclValue::Dict(d) => {
                let mut map = serde_json::Map::new();
                for (k, v) in d.into_iter() {
                    map.insert(k,Conf::from(v)).unwrap_or_default();
                }
                Value::Object(map)
            },
            SclValue::Array(a) => Value::Array(a
                .into_iter()
                .map(|v| Conf::from(v))
                .collect::<Vec<Value>>()),
            SclValue::Date(d) => {
                let mut map = serde_json::Map::new();
                map.insert(String::from("day"), serde_json::to_value(d.day).unwrap_or_default());
                map.insert(String::from("month"), serde_json::to_value(d.month).unwrap_or_default());
                map.insert(String::from("year"), serde_json::to_value(d.year).unwrap_or_default());
                Value::Object(map)
            }
        }

    }
}