slang

json

Package json.

Markdown version · llms.txt · api.json

json.decode/json.encode (de)serialize str/bytes against a concrete slang type — the target type for decode is inferred from the binding's annotation, the same mechanism ok()/err() already use to infer result[T,E]. There is no dynamic "JSON value" type: every decode is checked field-by-field against the struct shape you asked for, and a mismatch is a result error, not a silent null or a runtime panic.

import "json";

gc struct Address { city: str, zip: str }
gc struct Person {
    name: str,
    age: i32,
    email: opt[str],      // JSON null / missing key <-> none
    tags: [str],
    addr: Address,         // structs nest
}

let p = Person{ name: "Ada", age: 36, email: some("ada@example.com"),
                tags: ["math"], addr: Address{ city: "London", zip: "SW1" } };
let s: str = json.encode(p);

let r: result[Person, str] = json.decode(s);
guard let p2 = r else { exit(1); }

Supported: struct, opt[T], [T], map[str, V] (JSON object keys are always strings — a map with any other key type is a compile error), every scalar, and bytes (RFC 4648 base64 strings on the wire). rawptr, chan[T], and result[T,E] can't appear anywhere in a decode/encode target type. A missing JSON key defaults an opt[T] field to none; for any other field type it's a decode error. Unknown JSON keys are ignored. Every decode error names where it happened, composed through nesting — json.decode on {"addr":{"city":5}} against the Person shape above fails with field 'addr': field 'city': expected a string, got a number. Malformed input is a decode error, never a crash — the parser caps nesting depth at 512 so adversarial input can't blow the C stack.