docs / Getting Started / system.json

system.json

system.json is a recursive Json enum with a parser and serializer written in Miri itself — the compiler has no special knowledge of it. Parse failures carry the line and column where the document went wrong.

use system.io
use system.json

fn main()
    let source = "{\"name\": \"miri\", \"stars\": 3, \"tags\": [\"gpu\", \"compiler\"]}"

    // parse returns Result<Json, JsonError>; the error carries line and column.
    match Json.parse(source)
        Result.Ok(doc)
            // get(key) and at(index) return Json?, so a missing field is a
            // value you handle, not a crash.
            match doc.get("name")
                Some(field)
                    let name = field.as_string() ?? "<unnamed>"
                    println(f"name: {name}")
                None: println("no name field")

            match doc.get("stars")
                Some(field)
                    let stars = field.as_int() ?? 0
                    println(f"stars: {stars}")
                None: println("no stars field")

            match doc.get("tags")
                Some(tags)
                    match tags.at(0)
                        Some(first)
                            let tag = first.as_string() ?? "?"
                            println(f"first tag: {tag}")
                        None: println("no tags")
                None: println("no tags field")
        Result.Err(e): println(f"parse error: {e}")

The Json enum has six variants — Object, Array, Text, Number, Bool and Null — and you can match on them directly. Most code instead reaches for the accessors, each of which returns an option so a missing or mistyped field is a value rather than a crash:

MemberReturnsBehaviour
Json.parse(source String)Result<Json, JsonError>Static. Parses a document; the error carries a position.
to_string()StringSerializes back to JSON text.
get(key String)Json?An object member, or None.
at(index int)Json?An array element, or None.
as_string() / as_int() / as_float() / as_bool()String? / int? / float? / bool?The scalar value when the variant matches, else None.

Numbers keep their original lexeme, so a value written 1 stays 1 and no precision is lost on a round trip. Object members are stored in a map, so to_string() does not preserve the key order of the source document.