summaryrefslogtreecommitdiffstats
path: root/src/file/toml.rs
blob: 9e4b17009261308cad7c973726e1e7c68642b1b4 (plain)
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
use toml;
use source::Source;
use std::error::Error;
use value::Value;

pub struct Content {
    // Root table of the TOML document
    root: toml::Value,
}

impl Content {
    pub fn parse(text: &str) -> Result<Box<Source>, Box<Error>> {
        // Parse
        let mut parser = toml::Parser::new(text);
        // TODO: Get a solution to make this return an Error-able
        let root = parser.parse().unwrap();

        Ok(Box::new(Content { root: toml::Value::Table(root) }))
    }
}

fn from_toml_value(value: &toml::Value) -> Option<Value> {
    match *value {
        toml::Value::String(ref value) => Some(Value::String(value.clone())),
        toml::Value::Float(value) => Some(Value::Float(value)),
        toml::Value::Integer(value) => Some(Value::Integer(value)),
        toml::Value::Boolean(value) => Some(Value::Boolean(value)),

        _ => None,
    }
}

impl Source for Content {
    fn get(&self, key: &str) -> Option<Value> {
        // TODO: Key segment iteration is not something that should be here directly
        let key_delim = '.';
        let key_segments = key.split(key_delim);
        let mut toml_cursor = &self.root;
        for segment in key_segments {
            match *toml_cursor {
                toml::Value::Table(ref table) => {
                    if let Some(value) = table.get(segment) {
                        toml_cursor = value;
                    }
                }

                _ => {
                    // This is not a table or array
                    // Traversal is not possible
                    return None;
                }
            }
        }

        from_toml_value(toml_cursor)
    }
}