1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::collections::HashMap;
use super::ast;
use super::errors::ParseError;
use super::{parse_to_ast, ParseOptions};
use super::value::*;
pub fn parse_to_value(text: &str) -> Result<Option<JsonValue>, ParseError> {
let value = parse_to_ast(text, &ParseOptions {
comments: false,
tokens: false,
})?.value;
Ok(value.map(handle_value))
}
fn handle_value(value: ast::Value) -> JsonValue {
match value {
ast::Value::StringLit(lit) => JsonValue::String(lit.value.to_string()),
ast::Value::NumberLit(lit) => JsonValue::Number(lit.value.to_string()),
ast::Value::BooleanLit(lit) => JsonValue::Boolean(lit.value),
ast::Value::Object(obj) => JsonValue::Object(handle_object(obj)),
ast::Value::Array(arr) => JsonValue::Array(handle_array(arr)),
ast::Value::NullKeyword(_) => JsonValue::Null,
}
}
fn handle_array(arr: ast::Array) -> JsonArray {
let elements = arr.elements.into_iter().map(|element| {
handle_value(element)
}).collect();
JsonArray::new(elements)
}
fn handle_object(obj: ast::Object) -> JsonObject {
let mut props = HashMap::new();
for prop in obj.properties.into_iter() {
let prop_name = prop.name.to_string();
let prop_value = handle_value(prop.value);
props.insert(prop_name, prop_value);
}
JsonObject::new(props)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_should_parse_object() {
let value = parse_to_value(r#"{
"a": null,
"b": [null, "text"],
"c": true,
d: 25.55
}"#).unwrap().unwrap();
let mut object_map = HashMap::new();
object_map.insert(String::from("a"), JsonValue::Null);
object_map.insert(String::from("b"), JsonValue::Array(vec![JsonValue::Null, JsonValue::String(String::from("text"))].into()));
object_map.insert(String::from("c"), JsonValue::Boolean(true));
object_map.insert(String::from("d"), JsonValue::Number(String::from("25.55")));
assert_eq!(value, JsonValue::Object(object_map.into()));
}
#[test]
fn it_should_parse_boolean_false() {
let value = parse_to_value("false").unwrap().unwrap();
assert_eq!(value, JsonValue::Boolean(false));
let value = parse_to_value("true").unwrap().unwrap();
assert_eq!(value, JsonValue::Boolean(true));
}
#[test]
fn it_should_parse_boolean_true() {
let value = parse_to_value("true").unwrap().unwrap();
assert_eq!(value, JsonValue::Boolean(true));
}
#[test]
fn it_should_parse_number() {
let value = parse_to_value("50").unwrap().unwrap();
assert_eq!(value, JsonValue::Number(String::from("50")));
}
#[test]
fn it_should_parse_string() {
let value = parse_to_value(r#""test""#).unwrap().unwrap();
assert_eq!(value, JsonValue::String(String::from("test")));
}
#[test]
fn it_should_parse_array() {
let value = parse_to_value(r#"[false, true]"#).unwrap().unwrap();
assert_eq!(value, JsonValue::Array(vec![JsonValue::Boolean(false), JsonValue::Boolean(true)].into()));
}
#[test]
fn it_should_parse_null() {
let value = parse_to_value("null").unwrap().unwrap();
assert_eq!(value, JsonValue::Null);
}
#[test]
fn it_should_parse_empty() {
let value = parse_to_value("").unwrap();
assert_eq!(value.is_none(), true);
}
}