json¶
Parse a json string into candela values, and serialise candela values back to json.
Both functions wrap a built-in: json::parse is json_parse and
json::stringify is json_stringify. The module is pure candela, so it compiles
into a .cdlb artifact and runs under candela-vm with no dynamic library.
parse¶
text: the json document, as a string.- Returns: the parsed value, typed
any. - Raises:
json_parse_errorwhen the input is malformed. The message names the reason:unexpected end of input,object key must be a string,unterminated string,invalid number,invalid escape,trailing characters after value, and the rest.
Objects and arrays nest to a fixed depth, far beyond what a document written for
a program to read reaches. Text that nests deeper is rejected as malformed with
the reason nesting too deep, so a hostile document cannot exhaust the stack.
The mapping from json to candela is:
| json | candela |
|---|---|
| object | map keyed by strings |
| array | list |
| string | string |
| number without a fraction or exponent | int |
| number with a fraction or exponent | float |
true, false |
bool |
null |
null |
An object becomes a map that holds its keys in document order, which is the
order stringify writes them back out in.
The result is typed any, so read a field back with a downcast (as_int,
as_str, as_map, as_list) or test it first with is_int, is_map, and the
rest. Those are built-in functions. A document mixes types within
one object or array, and the downcast keeps that: the map as_map returns holds
any keys and values, so it takes an insert of a string beside an int.
import "std/json" as json;
fn main() {
let doc = json::parse("{\"name\": \"ada\", \"scores\": [1, 2, 3]}");
let obj = as_map(doc);
print(as_str(obj.get("name")));
print(as_list(obj.get("scores")).len());
}
stringify¶
value: any value.- Returns: a json string.
- Raises: nothing.
Ints, floats, bools, strings, null, lists, and maps serialise to their json
counterparts. A float keeps a decimal point so it parses back as a float, and a
float that is infinite or not a number serialises as null. A map key that is
not a string is rendered to its text form and quoted, because json object keys
are strings. A struct or enum value has no json shape, so it serialises as a
quoted string of its literal form. A map serialises in the order its keys went
in, so a document parsed with parse and handed straight back to stringify
keeps the key order it was written with.