Module: encoding.json

Source: ./encoding/json.reef


Overview

encoding/json - JSON parsing and generation

Provides functions to parse and generate JSON format data. Uses a flat representation with path-based keys for nested objects.

The parser is STRICT: malformed JSON syntax is rejected (not silently skipped/recovered), and the parsing functions return core.result.Result, not a bare value: Ok on a fully-valid, fully-consumed parse, Err(core.error.Error) on malformed syntax (InvalidInput) or an overflowed capacity (OutOfRange).

Usage (ergonomic struct API): import encoding.json import core.result as result let r = json.json_parse_doc(json_string) if result.is_ok(r) let doc = result.unwrap_ok(r) let name: string = json.json_get_doc(doc, "user.name") end if

Usage (low-level caller-array API): import encoding.json import core.result as result let keys: [string] = json_alloc_keys() let vals: [string] = json_alloc_values() let types: [int] = json_alloc_types() let r = json_parse(json_string, keys, vals, types) let count: int = result.unwrap_ok(r) let name: string = json_get(keys, vals, count, "user.name")


Types

ParseError

Fields:

Name Type
code int
pos int
msg string

JsonDoc

Fields:

Name Type
keys [string]
values [string]
types [int]
count int

JsonBuilder

Fields:

Name Type
sb sb.StringBuilder
has_item [bool]
depth int

Functions

fn int_to_char(n: int): char

Helper to convert int to char

fn char_to_int(c: char): int

Helper to convert char to int

fn JSON_TYPE_NULL(): int

fn JSON_TYPE_BOOL(): int

fn JSON_TYPE_NUMBER(): int

fn JSON_TYPE_STRING(): int

fn JSON_TYPE_ARRAY(): int

fn JSON_TYPE_OBJECT(): int

fn json_alloc_keys(): [string]

fn json_alloc_values(): [string]

fn json_alloc_types(): [int]

fn is_whitespace(c: char): bool

fn is_digit(c: char): bool

fn is_control_char(c: char): bool

JSON forbids literal (unescaped) control characters inside strings — only 0x20 and above may appear raw; anything below must be escaped.

fn skip_whitespace(input: string, pos: int): int

fn append_char(s: string, c: char): string

fn hex_digit_value(c: char): int

Value of a single hex digit, or -1 if c isn't 0-9/a-f/A-F.

fn parse_hex4(input: string, p: int): int

Parse exactly 4 hex digits starting at input[p..p+3]. Returns the resulting 16-bit value (0x0000-0xFFFF), or -1 if fewer than 4 chars remain or any of them isn't a hex digit.

fn parse_json_string(input: string, pos: int, out_pos: [int], perr: ParseError): string

Parse a JSON string (expects opening quote at pos). On malformed input (unterminated string, invalid/unsupported escape, raw control character) sets perr and returns immediately.

fn parse_json_number(input: string, pos: int, out_pos: [int], perr: ParseError): string

Parse a JSON number. Requires at least one integer digit, forbids a leading zero followed by more digits, and requires at least one digit after '.' and after 'e'/'E'. On malformed input sets perr and returns immediately.

fn str_to_int(s: string): int

Parse string to int

fn parse_json_value(input: string, pos: int, path: string, keys: [string], values: [string], types: [int], count: [int], max_entries: int, perr: ParseError): int

Parse a JSON value at position pos with given path prefix. Returns new position; stores entries in arrays. On malformed input sets perr and returns immediately (no further recovery). Once the caller-array capacity (max_entries) is reached, further parsing becomes a no-op that just returns the current position without consuming input or setting perr — callers detect this via count[0] >= max_entries and stop without treating it as a syntax fault; the public boundary (json_parse / json_parse_doc_sized) classifies leftover unconsumed input after a capacity-hit parse as Err(OutOfRange).

Trailing commas ([1,2,], {"a":1,}) are rejected per RFC 8259: after consuming a ',' in the array/object loops, the next non-whitespace char must not be the closing bracket/brace (or end-of-input) — otherwise perr is set to ERR_SYNTAX and parsing stops immediately.

fn json_default_capacity(): int

Default caller-array capacity, shared by json_parse and json_parse_doc.

fn json_parse(input: string, keys: [string], values: [string], types: [int]): result.Result[int, error.Error]

Low-level caller-array parse. Strict: rejects malformed JSON syntax and returns the entry count only for a fully-valid, fully-consumed top-level value. Ok(count) - valid JSON, entirely consumed Err(InvalidInput, ...) - malformed syntax (see the ParseError catalog threaded through parse_json_value/_string/_number) Err(OutOfRange, ...) - the caller-supplied arrays overflowed before the document ended (supersedes the old json_parse_status "-1" truncation signal)

fn json_parse_doc_sized(input: string, max_capacity: int): result.Result[JsonDoc, error.Error]

Parse with a caller-supplied capacity. Allocates fresh keys/values/types arrays sized to max_capacity, runs the strict engine, and translates a syntax or capacity fault into Err at this single boundary.

fn json_parse_doc(input: string): result.Result[JsonDoc, error.Error]

Parse with the default capacity (json_default_capacity() = 512).

fn json_get_doc(doc: JsonDoc, key: string): string

fn json_get_int_doc(doc: JsonDoc, key: string): int

fn json_get_bool_doc(doc: JsonDoc, key: string): bool

fn json_has_key_doc(doc: JsonDoc, key: string): bool

fn json_get_type_doc(doc: JsonDoc, key: string): int

fn json_get(keys: [string], values: [string], count: int, key: string): string

fn json_get_int(keys: [string], values: [string], count: int, key: string): int

fn json_get_bool(keys: [string], values: [string], count: int, key: string): bool

fn json_has_key(keys: [string], values: [string], count: int, key: string): bool

fn json_get_type(keys: [string], types: [int], count: int, key: string): int

fn json_escape_string(s: string): string

fn json_quote_string(s: string): string

fn json_builder(): JsonBuilder

fn json_render(b: JsonBuilder): string


Procedures

proc maybe_comma(b: JsonBuilder)

Emit a comma if the current scope already has an item, then mark this scope as having one. Refuses (writes nothing) if depth has overflowed.

proc push_depth(b: JsonBuilder)

Push a new nesting scope. Refuses to push past JSON_MAX_DEPTH; the extra-deep open is silently dropped at render-time, callers should keep nesting under 32 levels.

proc pop_depth(b: JsonBuilder)

proc emit_key(b: JsonBuilder, key: string)

Emit "key": prefix for object members.

proc json_set_string(b: JsonBuilder, key: string, value: string)

proc json_set_int(b: JsonBuilder, key: string, value: int)

proc json_set_bool(b: JsonBuilder, key: string, value: bool)

proc json_set_null(b: JsonBuilder, key: string)

proc json_begin_object(b: JsonBuilder, key: string)

proc json_end_object(b: JsonBuilder)

proc json_begin_array(b: JsonBuilder, key: string)

proc json_end_array(b: JsonBuilder)

proc json_array_append_string(b: JsonBuilder, value: string)

proc json_array_append_int(b: JsonBuilder, value: int)

proc json_array_append_bool(b: JsonBuilder, value: bool)

proc json_array_append_null(b: JsonBuilder)

proc json_array_begin_object(b: JsonBuilder)

proc json_array_begin_array(b: JsonBuilder)


Generated by reefc doc