convert json to toml before config parsing

This commit is contained in:
Gambhiro 2016-12-24 13:22:01 +00:00
parent 552e39c897
commit 97d46e79b7
2 changed files with 357 additions and 62 deletions

View File

@ -4,8 +4,8 @@ use std::process::exit;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
//use serde::{Serialize, Deserialize};
use std::collections::BTreeMap;
use std::str::FromStr;
use serde_json;
#[derive(Debug, Clone)]
@ -93,7 +93,29 @@ impl BookConfig {
}
};
// TODO this is very similar to how the JSON is parsed. Combine somehow?
self.parse_from_btreemap(&config);
self
}
/// Parses the string to JSON and converts it to BTreeMap<String, toml::Value>.
pub fn parse_from_json_string(&mut self, data: &String) -> &mut Self {
let c: serde_json::Value = match serde_json::from_str(&data) {
Ok(x) => x,
Err(e) => {
error!("[*]: JSON parse errors in book.json: {:?}", e);
exit(2);
}
};
let config = json_object_to_btreemap(&c.as_object().unwrap());
self.parse_from_btreemap(&config);
self
}
pub fn parse_from_btreemap(&mut self, config: &BTreeMap<String, toml::Value>) -> &mut Self {
// Title, author, description
if let Some(a) = config.get("title") {
@ -138,65 +160,6 @@ impl BookConfig {
self
}
pub fn parse_from_json_string(&mut self, data: &String) -> &mut Self {
let config: serde_json::Value = match serde_json::from_str(&data) {
Ok(x) => {x},
Err(e) => {
error!("[*]: JSON parse errors in book.json: {:?}", e);
exit(2);
}
};
// Extract data
let config = config.as_object().unwrap();
debug!("[*]: Extracting data from config");
// Title, author, description
if let Some(a) = config.get("title") {
self.title = a.to_string().replace("\"", "")
}
if let Some(a) = config.get("author") {
self.author = a.to_string().replace("\"", "")
}
if let Some(a) = config.get("description") {
self.description = a.to_string().replace("\"", "")
}
// Destination folder
if let Some(a) = config.get("dest") {
let mut dest = PathBuf::from(&a.to_string().replace("\"", ""));
// If path is relative make it absolute from the parent directory of src
if dest.is_relative() {
dest = self.get_root().join(&dest);
}
self.set_dest(&dest);
}
// Source folder
if let Some(a) = config.get("src") {
let mut src = PathBuf::from(&a.to_string().replace("\"", ""));
if src.is_relative() {
src = self.get_root().join(&src);
}
self.set_src(&src);
}
// Theme path folder
if let Some(a) = config.get("theme_path") {
let mut theme_path = PathBuf::from(&a.to_string().replace("\"", ""));
if theme_path.is_relative() {
theme_path = self.get_root().join(&theme_path);
}
self.set_theme_path(&theme_path);
}
self
}
pub fn get_root(&self) -> &Path {
&self.root
}
@ -233,3 +196,33 @@ impl BookConfig {
self
}
}
pub fn json_object_to_btreemap(json: &serde_json::Map<String, serde_json::Value>) -> BTreeMap<String, toml::Value> {
let mut config: BTreeMap<String, toml::Value> = BTreeMap::new();
for (key, value) in json.iter() {
config.insert(
String::from_str(key).unwrap(),
json_value_to_toml_value(value.to_owned())
);
}
config
}
pub fn json_value_to_toml_value(json: serde_json::Value) -> toml::Value {
match json {
serde_json::Value::Null => toml::Value::String("".to_string()),
serde_json::Value::Bool(x) => toml::Value::Boolean(x),
serde_json::Value::I64(x) => toml::Value::Integer(x),
serde_json::Value::U64(x) => toml::Value::Integer(x as i64),
serde_json::Value::F64(x) => toml::Value::Float(x),
serde_json::Value::String(x) => toml::Value::String(x),
serde_json::Value::Array(x) => {
toml::Value::Array(x.iter().map(|v| json_value_to_toml_value(v.to_owned())).collect())
},
serde_json::Value::Object(x) => {
toml::Value::Table(json_object_to_btreemap(&x))
},
}
}

View File

@ -1,6 +1,7 @@
#[cfg(test)]
use std::path::Path;
use serde_json;
use book::bookconfig::*;
#[test]
@ -61,3 +62,304 @@ author = "Mathieu David"
assert_eq!(format!("{:#?}", config), expected);
}
#[test]
fn it_parses_json_nested_array_to_toml() {
// Example from:
// toml-0.2.1/tests/valid/arrays-nested.json
let text = r#"
{
"nest": {
"type": "array",
"value": [
{"type": "array", "value": [
{"type": "string", "value": "a"}
]},
{"type": "array", "value": [
{"type": "string", "value": "b"}
]}
]
}
}"#;
let c: serde_json::Value = serde_json::from_str(&text).unwrap();
let result = json_object_to_btreemap(&c.as_object().unwrap());
let expected = r#"{
"nest": Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"string"
),
"value": String(
"a"
)
}
)
]
)
}
),
Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"string"
),
"value": String(
"b"
)
}
)
]
)
}
)
]
)
}
)
}"#;
assert_eq!(format!("{:#?}", result), expected);
}
#[test]
fn it_parses_json_arrays_to_toml() {
// Example from:
// toml-0.2.1/tests/valid/arrays.json
let text = r#"
{
"ints": {
"type": "array",
"value": [
{"type": "integer", "value": "1"},
{"type": "integer", "value": "2"},
{"type": "integer", "value": "3"}
]
},
"floats": {
"type": "array",
"value": [
{"type": "float", "value": "1.1"},
{"type": "float", "value": "2.1"},
{"type": "float", "value": "3.1"}
]
},
"strings": {
"type": "array",
"value": [
{"type": "string", "value": "a"},
{"type": "string", "value": "b"},
{"type": "string", "value": "c"}
]
},
"dates": {
"type": "array",
"value": [
{"type": "datetime", "value": "1987-07-05T17:45:00Z"},
{"type": "datetime", "value": "1979-05-27T07:32:00Z"},
{"type": "datetime", "value": "2006-06-01T11:00:00Z"}
]
}
}"#;
let c: serde_json::Value = serde_json::from_str(&text).unwrap();
let result = json_object_to_btreemap(&c.as_object().unwrap());
let expected = r#"{
"dates": Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"datetime"
),
"value": String(
"1987-07-05T17:45:00Z"
)
}
),
Table(
{
"type": String(
"datetime"
),
"value": String(
"1979-05-27T07:32:00Z"
)
}
),
Table(
{
"type": String(
"datetime"
),
"value": String(
"2006-06-01T11:00:00Z"
)
}
)
]
)
}
),
"floats": Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"float"
),
"value": String(
"1.1"
)
}
),
Table(
{
"type": String(
"float"
),
"value": String(
"2.1"
)
}
),
Table(
{
"type": String(
"float"
),
"value": String(
"3.1"
)
}
)
]
)
}
),
"ints": Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"integer"
),
"value": String(
"1"
)
}
),
Table(
{
"type": String(
"integer"
),
"value": String(
"2"
)
}
),
Table(
{
"type": String(
"integer"
),
"value": String(
"3"
)
}
)
]
)
}
),
"strings": Table(
{
"type": String(
"array"
),
"value": Array(
[
Table(
{
"type": String(
"string"
),
"value": String(
"a"
)
}
),
Table(
{
"type": String(
"string"
),
"value": String(
"b"
)
}
),
Table(
{
"type": String(
"string"
),
"value": String(
"c"
)
}
)
]
)
}
)
}"#;
assert_eq!(format!("{:#?}", result), expected);
}