chord_input/conf/
hocon.rs

1use std::path::Path;
2
3use hocon::{Hocon, HoconLoader};
4
5use chord_core::future::fs::metadata;
6use chord_core::value::{Map, Number, Value};
7
8pub type Error = hocon::Error;
9
10pub async fn load<P: AsRef<Path>>(dir_path: P, name: &str) -> Result<Value, Error> {
11    let file_path = dir_path.as_ref().join(format!("{}.conf", name));
12    let loader = HoconLoader::new();
13    let hocon = loader.strict().load_file(file_path)?.hocon()?;
14    convert(hocon)
15}
16
17pub async fn exists<P: AsRef<Path>>(dir_path: P, name: &str) -> bool {
18    let file_path = dir_path.as_ref().join(format!("{}.conf", name));
19    metadata(file_path).await.is_ok()
20}
21
22fn convert(hocon: Hocon) -> Result<Value, Error> {
23    let hv = match hocon {
24        Hocon::Null => Value::Null,
25        Hocon::Real(v) => {
26            Value::Number(Number::from_f64(v).ok_or_else(|| Error::Deserialization {
27                message: format!("{:?}", hocon),
28            })?)
29        }
30        Hocon::Integer(v) => Value::Number(Number::from(v)),
31        Hocon::String(v) => Value::String(v),
32        Hocon::Boolean(v) => Value::Bool(v),
33        Hocon::Array(vec) => {
34            let mut v: Vec<Value> = Vec::with_capacity(vec.len());
35            for i in vec {
36                let hv = convert(i)?;
37                v.push(hv)
38            }
39            Value::Array(v)
40        }
41        Hocon::Hash(hash) => {
42            let mut m = Map::new();
43            for (k, v) in hash {
44                let hv = convert(v)?;
45                m.insert(k, hv);
46            }
47            Value::Object(m)
48        }
49        Hocon::BadValue(_) => Err(Error::Deserialization {
50            message: format!("{:?}", hocon),
51        })?,
52    };
53    Ok(hv)
54}