jsonc_parser/
parse_to_value.rs

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