jsonc_parser/
parse_to_value.rs

1use 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
9/// Parses a string containing JSONC to a `JsonValue`.
10///
11/// Returns `None` when the provided string is empty or whitespace.
12///
13/// # Example
14///
15/// ```
16/// use jsonc_parser::parse_to_value;
17///
18/// let json_value = parse_to_value(r#"{ "test": 5 } // test"#, &Default::default()).expect("Should parse.");
19/// ```
20pub 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}