Merge branch 'json-parser'
This commit is contained in:
commit
27a1aecb08
8 changed files with 138 additions and 8 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
@ -8,6 +8,8 @@ dependencies = [
|
||||||
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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 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)",
|
"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)",
|
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -173,6 +175,23 @@ dependencies = [
|
||||||
"term 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -17,6 +17,9 @@ config = "0.1.2"
|
||||||
|
|
||||||
chrono = "0.2.16"
|
chrono = "0.2.16"
|
||||||
|
|
||||||
|
serde = "0.6.1"
|
||||||
|
serde_json = "0.6.0"
|
||||||
|
|
||||||
clap = { version = "1.4.5", features = ["yaml"] }
|
clap = { version = "1.4.5", features = ["yaml"] }
|
||||||
rustty = "0.1.9"
|
rustty = "0.1.9"
|
||||||
term = "0.2.12"
|
term = "0.2.12"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#[macro_use] extern crate clap;
|
#[macro_use] extern crate clap;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
#[macro_use] extern crate serde;
|
||||||
|
#[macro_use] extern crate serde_json;
|
||||||
extern crate config;
|
extern crate config;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
1
src/storage/json/mod.rs
Normal file
1
src/storage/json/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod parser;
|
103
src/storage/json/parser.rs
Normal file
103
src/storage/json/parser.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
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};
|
||||||
|
|
||||||
|
|
||||||
|
struct JsonHeaderParser<'a> {
|
||||||
|
spec: &'a FileHeaderSpec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FileHeaderParser<'a> for JsonHeaderParser<'a> {
|
||||||
|
|
||||||
|
fn new(spec: &'a FileHeaderSpec) -> JsonHeaderParser<'a> {
|
||||||
|
JsonHeaderParser {
|
||||||
|
spec: spec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self, string: Option<String>)
|
||||||
|
-> Result<FileHeaderData, ParserError>
|
||||||
|
{
|
||||||
|
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 {
|
||||||
|
Err(ParserError::short("Unknown JSON parser error", s.clone(), 0))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(FileHeaderData::Null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
|
||||||
|
let mut ser = Serializer::pretty(stdout());
|
||||||
|
data.serialize(&mut ser);
|
||||||
|
Ok(String::from(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for FileHeaderData {
|
||||||
|
|
||||||
|
fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: Ser
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
&FileHeaderData::Null => {
|
||||||
|
let o : Option<bool> = 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,3 +7,5 @@ pub use runtime::Runtime;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
|
pub mod json;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub struct ParserError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
ParserError {
|
||||||
summary: String::from(sum),
|
summary: String::from(sum),
|
||||||
parsertext: text,
|
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 {
|
ParserError {
|
||||||
summary: String::from(sum),
|
summary: String::from(sum),
|
||||||
parsertext: text,
|
parsertext: text,
|
||||||
|
@ -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> {
|
||||||
|
|
Loading…
Reference in a new issue