use super::ast::Value as AstValue;
use super::{errors::ParseError, parse_to_ast, ParseOptions};
use serde_json::Value as SerdeValue;
use std::str::FromStr;
pub fn parse_to_serde_value(text: &str) -> Result<Option<SerdeValue>, ParseError> {
let value = parse_to_ast(
text,
&ParseOptions {
comments: false,
tokens: false,
},
)?
.value;
Ok(value.map(to_serde))
}
fn to_serde(value: AstValue) -> SerdeValue {
match value {
AstValue::Array(arr) => {
let vec = arr.elements.into_iter().map(to_serde).collect();
SerdeValue::Array(vec)
}
AstValue::BooleanLit(bool) => SerdeValue::Bool(bool.value),
AstValue::NullKeyword(_) => SerdeValue::Null,
AstValue::NumberLit(num) => {
let number = serde_json::Number::from_str(num.value).expect("could not parse number");
SerdeValue::Number(number)
}
AstValue::Object(obj) => {
let mut map = serde_json::map::Map::new();
for prop in obj.properties.into_iter() {
map.insert(prop.name.into_string(), to_serde(prop.value));
}
SerdeValue::Object(map)
}
AstValue::StringLit(str) => SerdeValue::String(str.value.into_owned()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_error_when_has_error() {
assert_has_error(
"[][]",
"Text cannot contain more than one JSON value on line 1 column 3.",
);
}
fn assert_has_error(text: &str, message: &str) {
let result = parse_to_serde_value(text);
match result {
Ok(_) => panic!("Expected error, but did not find one."),
Err(err) => assert_eq!(err.to_string(), message),
}
}
#[test]
fn it_should_parse_to_serde_value() {
let result = parse_to_serde_value(
r#"{ "a": { "a1": 5 }, "b": [0.3e+025], "c": "c1", "d": true, "e": false, "f": null }"#,
)
.unwrap();
let mut expected_value = serde_json::map::Map::new();
expected_value.insert("a".to_string(), {
let mut inner_obj = serde_json::map::Map::new();
inner_obj.insert(
"a1".to_string(),
SerdeValue::Number(serde_json::Number::from_str("5").unwrap()),
);
SerdeValue::Object(inner_obj)
});
expected_value.insert("b".to_string(), {
let mut inner_array = Vec::new();
inner_array.push(SerdeValue::Number(
serde_json::Number::from_str("0.3e+025").unwrap(),
));
SerdeValue::Array(inner_array)
});
expected_value.insert("c".to_string(), SerdeValue::String("c1".to_string()));
expected_value.insert("d".to_string(), SerdeValue::Bool(true));
expected_value.insert("e".to_string(), SerdeValue::Bool(false));
expected_value.insert("f".to_string(), SerdeValue::Null);
assert_eq!(result, Some(SerdeValue::Object(expected_value)));
}
}