Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

std.json

RFC-8259 JSON parse and stringify, implemented in pure Bop.

Performance is reasonable for scripting workloads (config files, API payloads up to a few MB). A C-backed parser would be faster but would pull bop-std out of its zero-Rust-dep contract.

Import

use std.json                       // glob
use std.json.{parse, stringify}    // selective
use std.json as j                  // aliased

stringify(value)

Emit value as JSON text. Bop values that have no JSON analogue (fn, struct, enum) raise a runtime error — strip them out before calling.

use std.json.{stringify}

print(stringify(42))                           // "42"
print(stringify("hello"))                      // "\"hello\""
print(stringify([1, 2, 3]))                    // "[1,2,3]"
print(stringify({"name": "Alice", "age": 30})) // '{"name":"Alice","age":30}'
print(stringify(true))                         // "true"
print(stringify(none))                         // "null"

Strings are escaped for the five characters JSON requires (", \, \n, \r, \t). Other control characters under 0x20 are not currently escaped — fine for the common cases, but a known gap if you’re stringifying raw binary.

parse(text)

Parse JSON text into a Bop value. Parse errors raise a runtime error with a position marker.

use std.json.{parse}

print(parse("42"))                       // 42
print(parse("\"hello\""))                // "hello"
print(parse("[1, 2, 3]"))                // [1, 2, 3]
print(parse("{\"name\": \"Alice\"}"))    // {"name": "Alice"}
print(parse("null"))                     // none

Mapping

JSON typeBop type
number (integer)int
number (decimal / exponent)number
stringstring
booleanbool
nullnone
arrayarray
objectdict (keys must be strings, which JSON already requires)

Catching parse errors

parse raises on malformed input. Wrap in try_call if you want a Result-shaped outcome:

use std.json.{parse}

let r = try_call(fn() { return parse("\{broken") })
match r {
  Result::Ok(v)  => print("parsed: " + v.to_str()),
  Result::Err(e) => print("parse failed: " + e.message),
}
// parse failed: ...

(The leading \{ escapes the { so Bop doesn’t mistake it for a string-interpolation marker.)

Known gaps

  • \b / \f escapes are rejected. Rare in real payloads.
  • \uXXXX escapes are rejected — they’d need 4-hex parsing plus code-point-to-UTF-8 conversion, which is nontrivial in pure Bop.

Both raise a clear “unsupported escape” error so you know what happened.