json
Zero-copy JSON parser and serialiser. The parser returns slices that point directly into the source buffer – no allocations for strings. The serialiser writes directly to a caller-supplied buffer. Both are thread-safe (no global state).
Types
JsonValue (enum)
A tagged union covering all JSON types:
enum JsonValue {
Null
Bool(bool)
Int(i64)
Float(f64)
Str([]i8) // slice into original source buffer (zero-copy)
Array([]JsonValue) // elements stored in caller's region
Object([]JsonPair) // key-value pairs
}JsonPair (struct)
struct JsonPair {
key: []i8 // slice into source buffer
val: JsonValue
}Parser (struct)
struct Parser {
src: []i8
pos: i64
}Usage
Parsing JSON
import json
fn main() {
let src = "{\"name\": \"Jda\", \"version\": 1, \"fast\": true}"
let val = json_parse(src).unwrap()
let name = val.get("name").unwrap().as_str().unwrap()
let version = val.get("version").unwrap().as_i64().unwrap()
let fast = val.get("fast").unwrap().as_bool().unwrap()
}Writing JSON
import json
fn main() {
let val = JsonValue::Object([
JsonPair { key: "status", val: JsonValue::Str("ok") },
JsonPair { key: "code", val: JsonValue::Int(200) },
])
let buf = [4096]i8
let n = json_write(val, buf)
// buf now contains: {"status":"ok","code":200}
// Pretty-printed output
let n2 = json_write_pretty(val, buf)
}Function Reference
| Function | Signature | Description |
|---|---|---|
json_parse | (src: []i8) -> Result<JsonValue, []i8> | Parse a JSON string into a value |
json_write | (val: ref JsonValue, buf: []mut i8) -> i64 | Serialise to compact JSON |
json_write_pretty | (val: ref JsonValue, buf: []mut i8) -> i64 | Serialise to indented JSON |
Detailed API
json_parse
fn json_parse(src: []i8) -> Result<JsonValue, []i8>Parse a complete JSON document from src. Returns Ok(JsonValue) on success or Err(message) on failure. Trailing characters after the root value are an error.
let result = json_parse("{\"x\": 42}")
match result {
Ok(val) => {
let x = val.get("x").unwrap().as_i64().unwrap()
print(x) // 42
}
Err(msg) => {
// handle parse error
}
}Supported JSON types: null, booleans, integers, floating-point numbers, strings (with escape sequences), arrays, and objects.
json_write
fn json_write(val: ref JsonValue, buf: []mut i8) -> i64Serialise a JsonValue to compact JSON (no whitespace) into the provided buffer.
let val = JsonValue::Array([
JsonValue::Int(1),
JsonValue::Int(2),
JsonValue::Int(3),
])
let buf = [4096]i8
let n = json_write(val, buf)
// buf[0..n] contains: [1,2,3]Returns: Number of bytes written to buf.
json_write_pretty
fn json_write_pretty(val: ref JsonValue, buf: []mut i8) -> i64Serialise a JsonValue to indented JSON with 2-space indentation and newlines.
let val = JsonValue::Object([
JsonPair { key: "name", val: JsonValue::Str("Jda") },
])
let buf = [4096]i8
let n = json_write_pretty(val, buf)
// Output:
// {
// "name": "Jda"
// }Returns: Number of bytes written to buf.
JsonValue Methods
The JsonValue enum provides accessor methods for extracting typed values:
as_str
fn as_str(self) -> Result<[]i8, []i8>Extract the string slice from a Str variant.
let val = json_parse("\"hello\"").unwrap()
let s = val.as_str().unwrap() // "hello"as_i64
fn as_i64(self) -> Result<i64, []i8>Extract an integer from Int or truncate from Float.
let val = json_parse("42").unwrap()
let n = val.as_i64().unwrap() // 42as_f64
fn as_f64(self) -> Result<f64, []i8>Extract a float from Float or convert from Int.
let val = json_parse("3.14").unwrap()
let f = val.as_f64().unwrap() // 3.14as_bool
fn as_bool(self) -> Result<bool, []i8>Extract a boolean from a Bool variant.
is_null
fn is_null(self) -> boolReturns true if the value is Null.
get
fn get(self, key: ref []i8) -> Result<JsonValue, []i8>Look up a key in an Object. Returns Err("key not found") if the key does not exist or Err("not an object") if the value is not an object.
let obj = json_parse("{\"name\": \"Jda\"}").unwrap()
let name = obj.get("name").unwrap()index
fn index(self, i: i64) -> Result<JsonValue, []i8>Get an element by index from an Array.
let arr = json_parse("[10, 20, 30]").unwrap()
let second = arr.index(1).unwrap().as_i64().unwrap() // 20len
fn len(self) -> i64Get the length of an Array, Object, or Str. Returns 0 for other types.
let arr = json_parse("[1, 2, 3]").unwrap()
print(arr.len()) // 3