Skip to content

std.encoding.json

std.encoding.json is the native Janus JSON reader. It validates a borrowed byte slice once, returns a lightweight Document, and lets callers select values without building a heap-owned DOM.

The current reader is scalar and allocation-free. It handles objects, arrays, strings, numbers, booleans, and null. Strings are validated, including simple escapes and \uXXXX escape shape. Integer helpers return caller defaults when the selected value is missing, is not an integer-shaped number, or is outside the signed i64 range.

use std.encoding.json
var doc = json.parse("{\"service\":\"janus\",\"replicas\":3}")
if json.valid(&doc) do
const replicas = json.getInt(&doc, "replicas", 1)
end
pub struct Document
pub struct Value

Document and Value are borrowed views over the input bytes. Keep the input slice alive for as long as the views are used. There is no free call because the JSON reader does not allocate ownership for the parsed document.

pub func hasKey(view doc: *const Document, key: []const u8) -> bool
pub func get(view doc: *const Document, key: []const u8) -> Value
pub func getInt(view doc: *const Document, key: []const u8, default_val: i64) -> i64
pub func getBool(view doc: *const Document, key: []const u8, default_val: bool) -> bool
pub func valueHasKey(view value: *const Value, key: []const u8) -> bool
pub func valueGet(view value: *const Value, key: []const u8) -> Value
pub func valueGetInt(view value: *const Value, key: []const u8, default_val: i64) -> i64
pub func valueGetBool(view value: *const Value, key: []const u8, default_val: bool) -> bool
pub func arrayGet(view value: *const Value, index: i64) -> Value
pub func arrayGetInt(view value: *const Value, index: i64, default_val: i64) -> i64
pub func arrayGetBool(view value: *const Value, index: i64, default_val: bool) -> bool

Array indexes are zero-based. Negative array indexes count backward from the end, so -1 selects the last element and -2 selects the previous element. Out-of-range indexes return the supplied default for typed helpers.

Integer and boolean helpers preserve scalar type. Missing, null, wrong-kind, and out-of-i64-range integer values return the caller default.

Direct key lookup fast-matches unescaped object keys and decodes simple JSON escapes such as \n and \t. Unicode \uXXXX key matching remains unsupported.

Use hasKey, valueHasKey, pathHas, or valuePathHas for presence checks. They use a key-only scan for direct keys and final object-key path segments, avoiding the matched value body.

Use arrayGet when several checks target the same array element. It returns a borrowed Value view that can be passed to valueInt, valueBool, valueText*, or valueGet.

pub func select(view doc: *const Document, path: []const u8) -> Value
pub func pathHas(view doc: *const Document, path: []const u8) -> bool
pub func pathInt(view doc: *const Document, path: []const u8, default_val: i64) -> i64
pub func pathBool(view doc: *const Document, path: []const u8, default_val: bool) -> bool
pub func pathText(view doc: *const Document, path: []const u8) -> []const u8
pub func pathTextEquals(view doc: *const Document, path: []const u8, expected: []const u8) -> bool
pub func valueSelect(view value: *const Value, path: []const u8) -> Value
pub func valuePathHas(view value: *const Value, path: []const u8) -> bool
pub func valuePathInt(view value: *const Value, path: []const u8, default_val: i64) -> i64
pub func valuePathBool(view value: *const Value, path: []const u8, default_val: bool) -> bool
pub func valuePathCount(view value: *const Value, path: []const u8) -> i64
pub func valuePathText(view value: *const Value, path: []const u8) -> []const u8
pub func valuePathTextEquals(view value: *const Value, path: []const u8, expected: []const u8) -> bool
pub func valuePathTextContains(view value: *const Value, path: []const u8, needle: []const u8) -> bool
pub func valuePathTextStartsWith(view value: *const Value, path: []const u8, prefix: []const u8) -> bool
pub func valuePathTextEndsWith(view value: *const Value, path: []const u8, suffix: []const u8) -> bool

pathGet and valuePathGet remain as compatibility aliases for select and valueSelect.

Supported path forms are intentionally narrow:

FormMeaning
.key or keyObject member
$Root value
[0]Array element by absolute index
[-1]Array element from the end
["quoted.key"]Object key containing path punctuation

Forms compose, for example .items[-1]["display.name"].

valuePath* applies the same grammar relative to an existing Value. Use it after selecting a subtree once when several nested checks share the same base.

Quoted path keys accept raw bytes plus simple JSON-style escapes such as \" and \\, so callers can address keys containing quotes or backslashes. Unicode \uXXXX path-key escapes remain unsupported. Oversized indexes are rejected instead of wrapping.

pub func valueText(view value: *const Value) -> []const u8
pub func valueBool(view value: *const Value, default_val: bool) -> bool
pub func valueTextEquals(view value: *const Value, expected: []const u8) -> bool
pub func valueTextContains(view value: *const Value, needle: []const u8) -> bool
pub func valueTextStartsWith(view value: *const Value, prefix: []const u8) -> bool
pub func valueTextEndsWith(view value: *const Value, suffix: []const u8) -> bool
pub func valueTextEqualsC(view value: *const Value, expected: [*:0]const u8) -> bool
pub func valueTextContainsC(view value: *const Value, needle: [*:0]const u8) -> bool
pub func valueTextStartsWithC(view value: *const Value, prefix: [*:0]const u8) -> bool
pub func valueTextEndsWithC(view value: *const Value, suffix: [*:0]const u8) -> bool
pub func pathTextEquals(view doc: *const Document, path: []const u8, expected: []const u8) -> bool
pub func pathTextContains(view doc: *const Document, path: []const u8, needle: []const u8) -> bool
pub func pathTextStartsWith(view doc: *const Document, path: []const u8, prefix: []const u8) -> bool
pub func pathTextEndsWith(view doc: *const Document, path: []const u8, suffix: []const u8) -> bool
pub func valuePathTextEqualsC(view value: *const Value, path: []const u8, expected: [*:0]const u8) -> bool
pub func valuePathTextContainsC(view value: *const Value, path: []const u8, needle: [*:0]const u8) -> bool
pub func valuePathTextStartsWithC(view value: *const Value, path: []const u8, prefix: [*:0]const u8) -> bool
pub func valuePathTextEndsWithC(view value: *const Value, path: []const u8, suffix: [*:0]const u8) -> bool

valueText and pathText return borrowed unquoted bytes for strings that do not contain escapes. Non-string scalars return their JSON text. Containers and invalid values return an empty slice.

The text predicates decode simple JSON string escapes during comparison without allocating. This includes equality, contains, prefix, and suffix checks. Unicode \uXXXX comparison remains conservative until Janus grows a native UTF-8 decode helper.

Use the valueText* predicates after select or valueGet when several checks target the same value. That avoids reparsing the compact path for each predicate call.

Terminal window
cd janus
./scripts/zb test-json-janus
./scripts/zb test-json