diff --git a/src/storage/file.rs b/src/storage/file.rs index 0270f5ea..008b2d9c 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -175,10 +175,10 @@ pub struct File { id : String } -impl File { +impl<'a, D: FileData> File { fn new(prs: &Parser, path: &String) -> Result, ParserError> - where HP: FileHeaderParser, + where HP: FileHeaderParser<'a>, DP: FileDataParser, { File::::read_file(path).and_then(|p| prs.read(p)) diff --git a/src/storage/json/parser.rs b/src/storage/json/parser.rs index 0e275ca3..f915e7fe 100644 --- a/src/storage/json/parser.rs +++ b/src/storage/json/parser.rs @@ -1,14 +1,17 @@ -use serde_json::Value; +use serde_json::{Value, from_str}; +use serde_json::error::Result as R; -use super::parser; +use super::super::parser::{FileHeaderParser, ParserError}; +use super::super::file::{FileHeaderSpec, FileHeaderData}; -struct JsonHeaderParser { - spec: &FileHeaderSpec, + +struct JsonHeaderParser<'a> { + spec: &'a FileHeaderSpec, } -impl FileHeaderParser for JsonHeaderParser { +impl<'a> FileHeaderParser<'a> for JsonHeaderParser<'a> { - fn new(spec: &FileHeaderSpec) -> JsonHeaderParser { + fn new(spec: &'a FileHeaderSpec) -> JsonHeaderParser<'a> { JsonHeaderParser { spec: spec } @@ -17,9 +20,17 @@ impl FileHeaderParser for JsonHeaderParser { fn read(&self, string: Option) -> Result { - if let Ok(content) = data = serde_json::from_str(&string[..]) { + if (string.is_some()) { + let s = string.unwrap(); + debug!("Deserializing: {}", s); + let fromstr : R = from_str(&s[..]); + if let Ok(content) = fromstr { + Ok(visit_json(&content)) + } else { + Err(ParserError::short("Unknown JSON parser error", s.clone(), 0)) + } } else { - ParserError::short("Unknown JSON parser error", string.clone(), 0) + Ok(FileHeaderData::Null) } } @@ -28,3 +39,29 @@ impl FileHeaderParser for JsonHeaderParser { } +// TODO: This function must be able to return a parser error +fn visit_json(v: &Value) -> FileHeaderData { + match v { + &Value::Null => FileHeaderData::Null, + &Value::Bool(b) => FileHeaderData::Bool(b), + &Value::I64(i) => FileHeaderData::Integer(i), + &Value::U64(u) => FileHeaderData::UInteger(u), + &Value::F64(f) => FileHeaderData::Float(f), + &Value::String(ref s) => FileHeaderData::Text(s.clone()), + &Value::Array(ref vec) => { + FileHeaderData::Array { + values: Box::new(vec.clone().into_iter().map(|i| visit_json(v)).collect()) + } + }, + &Value::Object(ref btree) => { + FileHeaderData::Map{ + keys: btree.clone().iter().map(|(k, v)| + FileHeaderData::Key { + name: k.clone(), + value: Box::new(visit_json(v)), + } + ).collect() + } + } + } +} diff --git a/src/storage/parser.rs b/src/storage/parser.rs index ae6198a3..f470c779 100644 --- a/src/storage/parser.rs +++ b/src/storage/parser.rs @@ -74,8 +74,8 @@ impl Display for ParserError { } -pub trait FileHeaderParser : Sized { - fn new(spec: &FileHeaderSpec) -> Self; +pub trait FileHeaderParser<'a> : Sized { + fn new(spec: &'a FileHeaderSpec) -> Self; fn read(&self, string: Option) -> Result; fn write(&self, data: &FileHeaderData) -> Result; } @@ -94,8 +94,8 @@ pub struct Parser datap : DP, } -impl Parser where - HP: FileHeaderParser, +impl<'a, HP, DP> Parser where + HP: FileHeaderParser<'a>, { fn new(headerp: HP, datap: DP) -> Parser {