From 7b6ff6ac134350d394d4e1d34927ed4e492e4a64 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 8 Nov 2015 17:31:51 +0100 Subject: [PATCH 1/6] Add dep: serde_json --- Cargo.lock | 18 ++++++++++++++++++ Cargo.toml | 2 ++ 2 files changed, 20 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 0ea6483a..2743e2eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ dependencies = [ "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "term_grid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -173,6 +174,23 @@ dependencies = [ "term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "strsim" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 58109d21..911aca26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ config = "0.1.2" chrono = "0.2.16" +serde_json = "0.6.0" + clap = { version = "1.4.5", features = ["yaml"] } rustty = "0.1.9" term = "0.2.12" From b21186260286bec8fe90efac4645afd51cc0201a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 8 Nov 2015 17:32:43 +0100 Subject: [PATCH 2/6] Add json deserializer --- src/main.rs | 1 + src/storage/json/mod.rs | 1 + src/storage/json/parser.rs | 30 ++++++++++++++++++++++++++++++ src/storage/mod.rs | 2 ++ 4 files changed, 34 insertions(+) create mode 100644 src/storage/json/mod.rs create mode 100644 src/storage/json/parser.rs diff --git a/src/main.rs b/src/main.rs index 70e0ce03..b9129280 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #[macro_use] extern crate clap; #[macro_use] extern crate log; +#[macro_use] extern crate serde_json; extern crate config; extern crate regex; diff --git a/src/storage/json/mod.rs b/src/storage/json/mod.rs new file mode 100644 index 00000000..67c567fa --- /dev/null +++ b/src/storage/json/mod.rs @@ -0,0 +1 @@ +pub mod parser; diff --git a/src/storage/json/parser.rs b/src/storage/json/parser.rs new file mode 100644 index 00000000..0e275ca3 --- /dev/null +++ b/src/storage/json/parser.rs @@ -0,0 +1,30 @@ +use serde_json::Value; + +use super::parser; + +struct JsonHeaderParser { + spec: &FileHeaderSpec, +} + +impl FileHeaderParser for JsonHeaderParser { + + fn new(spec: &FileHeaderSpec) -> JsonHeaderParser { + JsonHeaderParser { + spec: spec + } + } + + fn read(&self, string: Option) + -> Result + { + if let Ok(content) = data = serde_json::from_str(&string[..]) { + } else { + ParserError::short("Unknown JSON parser error", string.clone(), 0) + } + } + + fn write(&self, data: &FileHeaderData) -> Result { + } + +} + diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 5a17befe..252f6001 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -7,3 +7,5 @@ pub use runtime::Runtime; pub mod file; pub mod parser; +pub mod json; + From fd35a003818656e649491dc2af242d36a60d7ed1 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 9 Nov 2015 00:03:10 +0100 Subject: [PATCH 3/6] Implement JSON to FileHeaderData parser --- src/storage/file.rs | 4 +-- src/storage/json/parser.rs | 53 ++++++++++++++++++++++++++++++++------ src/storage/parser.rs | 8 +++--- 3 files changed, 51 insertions(+), 14 deletions(-) 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 { From e8e82f684447ea277444dea2553c81eb9ca23581 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 9 Nov 2015 16:02:21 +0100 Subject: [PATCH 4/6] Make functions public --- src/storage/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/parser.rs b/src/storage/parser.rs index f470c779..8013ef97 100644 --- a/src/storage/parser.rs +++ b/src/storage/parser.rs @@ -13,7 +13,7 @@ pub struct ParserError { } impl ParserError { - fn new(sum: &'static str, text: String, idx: i32, expl: &'static str) -> ParserError { + pub fn new(sum: &'static str, text: String, idx: i32, expl: &'static str) -> ParserError { ParserError { summary: String::from(sum), parsertext: text, @@ -22,7 +22,7 @@ impl ParserError { } } - fn short(sum: &'static str, text: String, idx: i32) -> ParserError { + pub fn short(sum: &'static str, text: String, idx: i32) -> ParserError { ParserError { summary: String::from(sum), parsertext: text, From 9167fde4fbf33a6227a66df6363d316369f1d8a4 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 9 Nov 2015 18:33:44 +0100 Subject: [PATCH 5/6] Add dependency: serde --- Cargo.lock | 1 + Cargo.toml | 1 + src/main.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 2743e2eb..bc8ed48b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ dependencies = [ "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "term_grid 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 911aca26..02766913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ config = "0.1.2" chrono = "0.2.16" +serde = "0.6.1" serde_json = "0.6.0" clap = { version = "1.4.5", features = ["yaml"] } diff --git a/src/main.rs b/src/main.rs index b9129280..fd57f95e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #[macro_use] extern crate clap; #[macro_use] extern crate log; +#[macro_use] extern crate serde; #[macro_use] extern crate serde_json; extern crate config; extern crate regex; From e3afb3c0f3b4b23b735da78da5c84cd657ed62e0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 9 Nov 2015 18:34:28 +0100 Subject: [PATCH 6/6] Implement Serialization for FileHeaderData --- src/storage/json/parser.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/storage/json/parser.rs b/src/storage/json/parser.rs index f915e7fe..a033cdf3 100644 --- a/src/storage/json/parser.rs +++ b/src/storage/json/parser.rs @@ -1,5 +1,11 @@ use serde_json::{Value, from_str}; use serde_json::error::Result as R; +use serde_json::Serializer; +use serde::ser::Serialize; +use serde::ser::Serializer as Ser; + +use std::collections::HashMap; +use std::io::stdout; use super::super::parser::{FileHeaderParser, ParserError}; use super::super::file::{FileHeaderSpec, FileHeaderData}; @@ -35,6 +41,9 @@ impl<'a> FileHeaderParser<'a> for JsonHeaderParser<'a> { } fn write(&self, data: &FileHeaderData) -> Result { + let mut ser = Serializer::pretty(stdout()); + data.serialize(&mut ser); + Ok(String::from("")) } } @@ -65,3 +74,30 @@ fn visit_json(v: &Value) -> FileHeaderData { } } } + +impl Serialize for FileHeaderData { + + fn serialize(&self, ser: &mut S) -> Result<(), S::Error> + where S: Ser + { + match self { + &FileHeaderData::Null => { + let o : Option = None; + o.serialize(ser) + }, + &FileHeaderData::Bool(ref b) => b.serialize(ser), + &FileHeaderData::Integer(ref i) => i.serialize(ser), + &FileHeaderData::UInteger(ref u) => u.serialize(ser), + &FileHeaderData::Float(ref f) => f.serialize(ser), + &FileHeaderData::Text(ref s) => (&s[..]).serialize(ser), + &FileHeaderData::Array{values: ref vs} => vs.serialize(ser), + &FileHeaderData::Map{keys: ref ks} => ks.serialize(ser), + &FileHeaderData::Key{name: ref n, value: ref v} => { + let mut hm = HashMap::new(); + hm.insert(n, v); + hm.serialize(ser) + } + } + } + +}