summaryrefslogtreecommitdiffstats
path: root/src/file/json.rs
blob: 05af06544f13d616f3cefc5bfcb25514a3f13c5d (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
58
59
60
61
62
63
64
65
use serde_json;

use source::Source;
use std::error::Error;
use value::Value;

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

impl Content {
    pub fn parse(text: &str) -> Result<Box<Source>, Box<Error>> {
        // Parse
        let root = serde_json::from_str(text)?;

        Ok(Box::new(Content { root: root }))
    }
}

fn from_json_value(value: &serde_json::Value) -> Option<Value> {
    match *value {
        serde_json::Value::String(ref value) => Some(Value::String(value.clone())),

        serde_json::Value::Number(ref value) => {
            if let Some(value) = value.as_i64() {
                Some(Value::Integer(value))
            } else if let Some(value) = value.as_f64() {
                Some(Value::Float(value))
            } else {
                None
            }
        }

        serde_json::Value::Bool(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 json_cursor = &self.root;
        for segment in key_segments {
            match *json_cursor {
                serde_json::Value::Object(ref table) => {
                    if let Some(value) = table.get(segment) {
                        json_cursor = value;
                    }
                }

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

        from_json_value(json_cursor)
    }
}