pub fn field(self: const JsonValue, name: text) -> JsonValue[self]
JObject indexer — returns the value at name, or JNull when self isn't a JObject or the key is missing. Chained access like root.field("a").field("b") is safe — every intermediate missing produces JNull, never a trap.
pub fn item(self: const JsonValue, index: integer) -> JsonValue[self]
JArray indexer — returns the element at index, or JNull when self isn't a JArray or the index is out of bounds.
pub fn len(self: const JsonValue) -> integer
Length of a JArray's items vector or a JObject's fields vector. Returns null for any other variant.
pub fn as_text(self: const JsonValue) -> text
Typed extractor — returns null on kind mismatch.
The null is NOT the empty text, and only ?? tells the two apart: on a mismatch s == "" is false and len(s) is 1, while a field that really holds "" compares equal and measures 0. Reach for as_text(...) ?? fallback, never == "".
pub fn as_long(self: const JsonValue) -> integer
Typed extractor — returns null on kind mismatch. A JInteger answers its exact value; a JNumber is truncated toward zero.
pub fn as_bool(self: const JsonValue) -> boolean?
Typed extractor — returns null on kind mismatch.
Declared boolean?, so a mismatch — an absent field, the string "true", the number 1 — is null and never reads as a field that really says false.
pub fn kind(self: const JsonValue) -> text
Returns the variant name as text: "JNull", "JBool", "JNumber", "JString", "JArray", "JObject" or "JInteger". Cheap: reads the discriminant byte, formats a literal. Useful for logs and conditional branches that don't want to commit to a full pattern match.
pub fn keys(self: const JsonValue) -> vector<text>
Returns the field-name list of a JObject in insertion order, or an empty vector for any other variant. Safe idiom: for k in v.keys() { ... } works on any JsonValue because non-objects yield an empty walk.
pub fn fields(self: const JsonValue) -> vector<JsonField>
Returns the (name, value) entries of a JObject in insertion order so callers can iterate as for entry in fields(v) { … entry.name … entry.value … }. Values deep-copy (primitives + nested containers — full tree). Empty vector for any other variant.
pub fn has_field(self: const JsonValue, name: text) -> boolean
Returns true iff self is a JObject variant carrying a field named name. All other variants (including JNull on a parse error) return false, so the common pattern if v.has_field("users") { … } is safe to write on any JsonValue without first destructuring. Distinguishes "absent" from "present-but-null" — a field whose value is JNull still returns true.