-
-
Notifications
You must be signed in to change notification settings - Fork 51
/
kdl_source.rs
67 lines (60 loc) · 1.98 KB
/
kdl_source.rs
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use config::{ConfigError, FileStoredFormat, Format, Map, Source, Value, ValueKind};
use kdl::{KdlDocument, KdlValue};
#[derive(Clone, Debug)]
pub(crate) struct KdlSource(KdlDocument);
impl Source for KdlSource {
fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
Box::new(self.clone())
}
fn collect(&self) -> Result<Map<String, Value>, ConfigError> {
let mut map = Map::new();
if let Some(config_node) = self.0.get("options") {
if let Some(children) = config_node.children() {
for node in children.nodes() {
let key = node.name().to_string();
if let Some(value) = node.get(0) {
let value = Value::new(
Some(&if let Some(str) = value.as_string() {
str.to_owned()
} else {
value.to_string()
}),
value_kind(value),
);
map.insert(key, value);
}
}
}
}
Ok(map)
}
}
#[derive(Clone, Debug)]
pub(crate) struct KdlFormat;
impl Format for KdlFormat {
fn parse(
&self,
_uri: Option<&String>,
text: &str,
) -> Result<Map<String, Value>, Box<dyn std::error::Error + Send + Sync>> {
Ok(KdlSource(text.parse()?).collect()?)
}
}
impl FileStoredFormat for KdlFormat {
fn file_extensions(&self) -> &'static [&'static str] {
&["kdl"]
}
}
fn value_kind(value: &KdlValue) -> ValueKind {
if let Some(str) = value.as_string() {
ValueKind::String(str.into())
} else if let Some(num) = value.as_i64() {
ValueKind::I64(num)
} else if let Some(float) = value.as_f64() {
ValueKind::Float(float)
} else if let Some(boolean) = value.as_bool() {
ValueKind::Boolean(boolean)
} else {
ValueKind::Nil
}
}