moonjson — the JSON family for MoonBit: RFC 8259 JSON, JSONC, JSON5 and JSON Lines over one data model, with JSON Pointer, and failures that name the line and column.
let config = @json.loads("{\"host\":\"localhost\",\"port\":8080}")
@json.dumps(config) // {"host":"localhost","port":8080}
@json.dumps(config, indent=2) // over several lines
// The same document, written the way a settings file is written.
@jsonc.loads("{\"port\": 8080, // the one we bound\n}")
// One place in a document, named (RFC 6901).
@pointer.get(config, "/host") // "localhost"| text → tree | bytes → tree | tree → text | tree → bytes | |
|---|---|---|---|---|
| one document | loads | load | dumps | dump |
| a stream of them | loads_all | load_all | dumps_all | dump_all |
// Read a document, change one field, write it back.
let cfg = @jsonc.loads(text[:])
let cfg = @pointer.set(cfg, "/spec/replicas", Json::number(5))
@json.dumps(cfg, indent=2)| Package | What | Specification |
|---|---|---|
| json | JSON, exactly | RFC 8259, ECMA-404 |
| jsonc | JSON with comments and trailing commas | what VS Code accepts |
| json5 | JSON5: unquoted names, single quotes, hexadecimal, Infinity | spec.json5.org |
| lines | JSON Lines / NDJSON: one document to a line | jsonlines.org |
| pointer | JSON Pointer | RFC 6901 |
| moonjson | The scanner the dialects share, the writer, and Flavor | — |
@json.loads(text) // strict JSON
@jsonc.loads(text) // the same, plus comments
@json.loads(text, flavor=@moonjson.Flavor::new(depth=100))
@json.loads(text, flavor={ ..@moonjson.strict, duplicates: Reject })@json.dumps(value) // compact
@json.dumps(value, indent=2) // over several lines
@json.dumps(value, ascii=true) // escape everything above U+007E
@json.dumps(value, sort=true) // members in order of name| Setting | Default | Why that one |
|---|---|---|
| depth | 500 | Everyone bounds it and nobody agrees on the number — Jackson refuses past 1000, serde_json past 128. A hundred thousand open brackets is a denial of service, not a document |
| surrogates | refuse | Implementations disagree and JSONTestSuite files these cases as implementation-defined, so the safer side is the default: a lone half cannot be written back out |
| duplicates | Last | JavaScript, Python, Go and serde all keep the last one |
| bom | skipped | RFC 8259 §8.1 forbids writing one and says nothing about reading one; refusing would reject half of what Windows tooling produces |
| ascii | off | A UTF-8 body is the normal case now. Python's ensure_ascii defaults the other way because it predates that |
| sort | off | The order a document was written in is information; a diff is the reason to discard it, and a diff can ask |
try @json.loads(source) catch {
e => println("line \{e.at().line}, column \{e.at().column}")
}moon add moonbitstack/moonjsonpub(all) struct Flavor {
comments : Bool
trailing_commas : Bool
unquoted_keys : Bool
single_quotes : Bool
extra_numbers : Bool
extra_escapes : Bool
extra_space : Bool
depth : Int
surrogates : Bool
duplicates : Duplicates
} derive(Eq, Debug)fn Flavor::new(comments? : Bool, trailing_commas? : Bool, unquoted_keys? : Bool, single_quotes? : Bool, extra_numbers? : Bool, extra_escapes? : Bool, extra_space? : Bool, depth? : Int, surrogates? : Bool, duplicates? : Duplicates) -> FlavorInstall
Download zipmoonjson — the JSON family for MoonBit: RFC 8259 JSON, JSONC, JSON5 and JSON Lines over one data model, with JSON Pointer, and failures that name the line and column.