Treat leading #{ in Engine::parse_json.

This commit is contained in:
Stephen Chung
2020-08-18 22:01:13 +08:00
parent f9807a3c1e
commit e3f2157c6a
3 changed files with 54 additions and 10 deletions

View File

@@ -7,7 +7,7 @@ The syntax for an [object map] is extremely similar to JSON, with the exception
technically be mapped to [`()`]. A valid JSON string does not start with a hash character `#` while a
Rhai [object map] does - that's the major difference!
Use the `Engine::parse_json` method to parse a piece of JSON into an object map:
Use the `Engine::parse_json` method to parse a piece of _simple_ JSON into an object map:
```rust
// JSON string - notice that JSON property names are always quoted
@@ -26,7 +26,7 @@ let json = r#"{
// Set the second boolean parameter to true in order to map 'null' to '()'
let map = engine.parse_json(json, true)?;
map.len() == 6; // 'map' contains all properties in the JSON string
map.len() == 6; // 'map' contains all properties in the JSON string
// Put the object map into a 'Scope'
let mut scope = Scope::new();
@@ -34,7 +34,7 @@ scope.push("map", map);
let result = engine.eval_with_scope::<INT>(r#"map["^^^!!!"].len()"#)?;
result == 3; // the object map is successfully used in the script
result == 3; // the object map is successfully used in the script
```
Representation of Numbers
@@ -45,3 +45,28 @@ the [`no_float`] feature is not used. Most common generators of JSON data disti
integer and floating-point values by always serializing a floating-point number with a decimal point
(i.e. `123.0` instead of `123` which is assumed to be an integer). This style can be used successfully
with Rhai [object maps].
Parse JSON with Sub-Objects
--------------------------
`Engine::parse_json` depends on the fact that the [object map] literal syntax in Rhai is _almost_
the same as a JSON object. However, it is _almost_ because the syntax for a sub-object in JSON
(i.e. "`{ ... }`") is different from a Rhai [object map] literal (i.e. "`#{ ... }`").
When `Engine::parse_json` encounters JSON with sub-objects, it fails with a syntax error.
If it is certain that no text string in the JSON will ever contain the character '`{`',
then it is possible to parse it by first replacing all occupance of '`{`' with "`#{`".
```rust
// JSON with sub-object 'b'.
let json = r#"{"a":1, "b":{"x":true, "y":false}}"#;
let new_json = json.replace("{" "#{");
// The leading '{' will also be replaced to '#{', but parse_json can handle this.
let map = engine.parse_json(&new_json, false)?;
map.len() == 2; // 'map' contains two properties: 'a' and 'b'
```