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