Implement JSON to FileHeaderData parser

This commit is contained in:
Matthias Beyer 2015-11-09 00:03:10 +01:00
parent b211862602
commit fd35a00381
3 changed files with 51 additions and 14 deletions

View file

@ -175,10 +175,10 @@ pub struct File<D: FileData> {
id : String id : String
} }
impl<D: FileData> File<D> { impl<'a, D: FileData> File<D> {
fn new<HP, DP>(prs: &Parser<HP, DP>, path: &String) -> Result<File<D>, ParserError> fn new<HP, DP>(prs: &Parser<HP, DP>, path: &String) -> Result<File<D>, ParserError>
where HP: FileHeaderParser, where HP: FileHeaderParser<'a>,
DP: FileDataParser<D>, DP: FileDataParser<D>,
{ {
File::<D>::read_file(path).and_then(|p| prs.read(p)) File::<D>::read_file(path).and_then(|p| prs.read(p))

View file

@ -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 { JsonHeaderParser {
spec: spec spec: spec
} }
@ -17,9 +20,17 @@ impl FileHeaderParser for JsonHeaderParser {
fn read(&self, string: Option<String>) fn read(&self, string: Option<String>)
-> Result<FileHeaderData, ParserError> -> Result<FileHeaderData, ParserError>
{ {
if let Ok(content) = data = serde_json::from_str(&string[..]) { if (string.is_some()) {
let s = string.unwrap();
debug!("Deserializing: {}", s);
let fromstr : R<Value> = from_str(&s[..]);
if let Ok(content) = fromstr {
Ok(visit_json(&content))
} else { } else {
ParserError::short("Unknown JSON parser error", string.clone(), 0) Err(ParserError::short("Unknown JSON parser error", s.clone(), 0))
}
} else {
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()
}
}
}
}

View file

@ -74,8 +74,8 @@ impl Display for ParserError {
} }
pub trait FileHeaderParser : Sized { pub trait FileHeaderParser<'a> : Sized {
fn new(spec: &FileHeaderSpec) -> Self; fn new(spec: &'a FileHeaderSpec) -> Self;
fn read(&self, string: Option<String>) -> Result<FileHeaderData, ParserError>; fn read(&self, string: Option<String>) -> Result<FileHeaderData, ParserError>;
fn write(&self, data: &FileHeaderData) -> Result<String, ParserError>; fn write(&self, data: &FileHeaderData) -> Result<String, ParserError>;
} }
@ -94,8 +94,8 @@ pub struct Parser<HP, DP>
datap : DP, datap : DP,
} }
impl<HP, DP> Parser<HP, DP> where impl<'a, HP, DP> Parser<HP, DP> where
HP: FileHeaderParser, HP: FileHeaderParser<'a>,
{ {
fn new(headerp: HP, datap: DP) -> Parser<HP, DP> { fn new(headerp: HP, datap: DP) -> Parser<HP, DP> {