jsonc_parser/
parse_to_value.rs1use super::ast;
2use super::errors::ParseError;
3use super::parse_to_ast;
4use super::value::*;
5use super::CollectOptions;
6use super::ParseOptions;
7use crate::value::Map;
8
9pub fn parse_to_value<'a>(text: &'a str, options: &ParseOptions) -> Result<Option<JsonValue<'a>>, ParseError> {
19 let value = parse_to_ast(
20 text,
21 &CollectOptions {
22 comments: crate::CommentCollectionStrategy::Off,
23 tokens: false,
24 },
25 options,
26 )?
27 .value;
28 Ok(value.map(handle_value))
29}
30
31fn handle_value(value: ast::Value) -> JsonValue {
32 match value {
33 ast::Value::StringLit(lit) => JsonValue::String(lit.value),
34 ast::Value::NumberLit(lit) => JsonValue::Number(lit.value),
35 ast::Value::BooleanLit(lit) => JsonValue::Boolean(lit.value),
36 ast::Value::Object(obj) => JsonValue::Object(handle_object(obj)),
37 ast::Value::Array(arr) => JsonValue::Array(handle_array(arr)),
38 ast::Value::NullKeyword(_) => JsonValue::Null,
39 }
40}
41
42fn handle_array(arr: ast::Array) -> JsonArray {
43 let elements = arr.elements.into_iter().map(handle_value).collect();
44
45 JsonArray::new(elements)
46}
47
48fn handle_object(obj: ast::Object) -> JsonObject {
49 let mut props = Map::with_capacity(obj.properties.len());
50 for prop in obj.properties.into_iter() {
51 let prop_name = prop.name.into_string();
52 let prop_value = handle_value(prop.value);
53 props.insert(prop_name, prop_value);
54 }
55 JsonObject::new(props)
56}
57
58#[cfg(test)]
59mod tests {
60 use crate::errors::ParseErrorKind;
61
62 use super::*;
63 use std::borrow::Cow;
64
65 #[test]
66 fn it_should_parse_object() {
67 let value = parse_to_value(
68 r#"{
69 "a": null,
70 "b": [null, "text"],
71 "c": true,
72 d: 25.55
73}"#,
74 &Default::default(),
75 )
76 .unwrap()
77 .unwrap();
78
79 let mut object_map = Map::new();
80 object_map.insert(String::from("a"), JsonValue::Null);
81 object_map.insert(
82 String::from("b"),
83 JsonValue::Array(vec![JsonValue::Null, JsonValue::String(Cow::Borrowed("text"))].into()),
84 );
85 object_map.insert(String::from("c"), JsonValue::Boolean(true));
86 object_map.insert(String::from("d"), JsonValue::Number("25.55"));
87 assert_eq!(value, JsonValue::Object(object_map.into()));
88 }
89
90 #[test]
91 fn it_should_parse_boolean_false() {
92 let value = parse_to_value("false", &Default::default()).unwrap().unwrap();
93 assert_eq!(value, JsonValue::Boolean(false));
94 let value = parse_to_value("true", &Default::default()).unwrap().unwrap();
95 assert_eq!(value, JsonValue::Boolean(true));
96 }
97
98 #[test]
99 fn it_should_parse_boolean_true() {
100 let value = parse_to_value("true", &Default::default()).unwrap().unwrap();
101 assert_eq!(value, JsonValue::Boolean(true));
102 }
103
104 #[test]
105 fn it_should_parse_number() {
106 let value = parse_to_value("50", &Default::default()).unwrap().unwrap();
107 assert_eq!(value, JsonValue::Number("50"));
108 }
109
110 #[test]
111 fn it_should_parse_string() {
112 let value = parse_to_value(r#""test""#, &Default::default()).unwrap().unwrap();
113 assert_eq!(value, JsonValue::String(Cow::Borrowed("test")));
114 }
115
116 #[test]
117 fn it_should_parse_string_with_quotes() {
118 let value = parse_to_value(r#""echo \"test\"""#, &Default::default())
119 .unwrap()
120 .unwrap();
121 assert_eq!(value, JsonValue::String(Cow::Borrowed(r#"echo "test""#)));
122 }
123
124 #[test]
125 fn it_should_parse_array() {
126 let value = parse_to_value(r#"[false, true]"#, &Default::default())
127 .unwrap()
128 .unwrap();
129 assert_eq!(
130 value,
131 JsonValue::Array(vec![JsonValue::Boolean(false), JsonValue::Boolean(true)].into())
132 );
133 }
134
135 #[test]
136 fn it_should_parse_null() {
137 let value = parse_to_value("null", &Default::default()).unwrap().unwrap();
138 assert_eq!(value, JsonValue::Null);
139 }
140
141 #[test]
142 fn it_should_parse_empty() {
143 let value = parse_to_value("", &Default::default()).unwrap();
144 assert!(value.is_none());
145 }
146
147 #[test]
148 fn error_unexpected_token() {
149 let err = parse_to_value("{\n \"a\":\u{200b}5 }", &Default::default())
150 .err()
151 .unwrap();
152 assert_eq!(err.range().start, 8);
153 assert_eq!(err.range().end, 11);
154 assert_eq!(err.kind().clone(), ParseErrorKind::UnexpectedToken);
155 }
156}