diff options
Diffstat (limited to 'src/file/json.rs')
-rw-r--r-- | src/file/json.rs | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/src/file/json.rs b/src/file/json.rs index 5f1c3a2..d193da4 100644 --- a/src/file/json.rs +++ b/src/file/json.rs @@ -2,7 +2,7 @@ use serde_json; use source::Source; use std::error::Error; -use std::borrow::Cow; +use std::collections::HashMap; use value::Value; pub struct Content { @@ -19,50 +19,57 @@ impl Content { } } -fn from_json_value<'a>(value: &serde_json::Value) -> Option<Cow<'a, Value>> { +fn from_json_value(value: &serde_json::Value) -> Value { match *value { serde_json::Value::String(ref value) => { - Some(Cow::Owned(Value::String(Cow::Borrowed(value)))) + Value::String(value.clone()) } serde_json::Value::Number(ref value) => { if let Some(value) = value.as_i64() { - Some(Cow::Owned(Value::Integer(value))) + Value::Integer(value) } else if let Some(value) = value.as_f64() { - Some(Cow::Owned(Value::Float(value))) + Value::Float(value) } else { - None + unreachable!(); } } - serde_json::Value::Bool(value) => Some(Cow::Owned(Value::Boolean(value))), + serde_json::Value::Bool(value) => Value::Boolean(value), - _ => None, - } -} + serde_json::Value::Object(ref table) => { + let mut m = HashMap::new(); -impl Source for Content { - fn get<'a>(&self, key: &str) -> Option<Cow<'a, 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; - } - } + for (key, value) in table { + m.insert(key.clone(), from_json_value(value)); + } + + Value::Table(m) + } + + serde_json::Value::Array(ref array) => { + let mut l = Vec::new(); - _ => { - // This is not a table or array - // Traversal is not possible - return None; - } + for value in array { + l.push(from_json_value(value)); } + + Value::Array(l) } - from_json_value(json_cursor) + // TODO: What's left is JSON Null; how should we handle that? + _ => { unimplemented!(); } + } +} + +impl Source for Content { + fn collect(&self) -> HashMap<String, Value> { + if let Value::Table(table) = from_json_value(&self.root) { + table + } else { + // TODO: Better handle a non-object at root + // NOTE: I never want to support that but a panic is bad + panic!("expected object at JSON root"); + } } } |