GizStack
View .mdOpen in ChatGPTOpen in Claude

gizlang:json

JSON (RFC 8259) as a value, read with parse and written with stringify as JavaScript's JSON.stringify writes it. Objects keep their keys in order; a repeated key keeps the last value, as JSON.parse.

gizlang
import * as Json from "gizlang:json";

Types

Json

gizlang
type Json = | { kind: "null"; } | { kind: "boolean"; value: bool; } | { kind: "number"; value: f64; } | { kind: "string"; value: string; } | { kind: "array"; items: Vec<Json>; } | { kind: "object"; keys: Vec<string>; values: Vec<Json>; }

A JSON value: null, boolean, number, string, array or object.

  • null
  • boolean
  • number
  • string
  • array
  • object

JsonError

gizlang
type JsonError = { offset: i64; message: string; }

Where the text stops being JSON, in bytes.

  • offset: i64
  • message: string

JsonReader

gizlang
type JsonReader

A reader that walks JSON text without building a tree.

Opaque: create and use it through this module's functions.

JsonSpan

gizlang
type JsonSpan = { start: i64; end: i64; }

Half-open UTF-8 byte offsets into the retained input, excluding surrounding whitespace.

  • start: i64
  • end: i64

Functions

parse

gizlang
function parse(text: string): Json throws JsonError

The JSON value of TEXT. It fails at the first error, with its offset.

Effects: fail.

parseUnique

gizlang
function parseUnique(text: string): Json throws JsonError

The same JSON parser, rejecting repeated decoded keys in every object. Use for manifests and authenticated contracts with one meaning per field.

Effects: fail.

parseBytes

gizlang
function parseBytes(data: bytes): Json throws JsonError

parse of JSON text in UTF-8 bytes; bytes that are not UTF-8 are an error at offset 0.

Effects: fail.

ofInteger

gizlang
function ofInteger(n: i64): Json

The number N.

strings

gizlang
function strings(values: Vec<string>): Json

A JSON array of the strings VALUES.

Effects: fail.

rpcResult

gizlang
function rpcResult(id: Json, result: Json): Json

The answer RESULT to the request ID.

Effects: fail.

rpcError

gizlang
function rpcError(id: Json, code: i64, message: string): Json

The error answer to the request ID (Json.null() when the request has no readable id).

Effects: fail.

rpcCall

gizlang
function rpcCall(id: Json, method: string, params: Json): Json

The request ID that calls METHOD with PARAMS.

Effects: fail.

rpcNotice

gizlang
function rpcNotice(method: string, params: Json): Json

A notification of METHOD: a request without an id, which gets no answer.

Effects: fail.

stringify

gizlang
function stringify(value: Json): string

As JSON.stringify: no spaces, a number as String(n) (NaN and Infinity as null), and a string with ", \ and control characters escaped.

Effects: fail.

stringifyIndented

gizlang
function stringifyIndented(value: Json, indent: i64): string

As JSON.stringify(value, null, indent): each item and key on its own line, indented indent spaces a level, "key": value; empty arrays and objects stay [] and {}.

Effects: fail.

stringifySpaced

gizlang
function stringifySpaced(value: Json): string

As Python's json.dumps (and the tojson of Jinja chat templates): one line, ", " between items and ": " after a key.

Effects: fail.

quote

gizlang
function quote(text: string): string

TEXT as a JSON string literal, quoted and escaped.

Effects: fail.

writeString

gizlang
function writeString(out: mut bytes, text: string): void

text as a JSON string, appended to out, for writing a typed value field by field (its keys and strings). A text with nothing to escape, nearly every one, is one scan and one copy.

Effects: fail.

integerDigits

gizlang
function integerDigits(n: i64): i64

The count of N's decimal digits, without its sign.

Effects: fail.

writeInteger

gizlang
function writeInteger(out: mut bytes, n: i64): void

Appends N's decimal digits: their room first, then the digits from the right, so none is moved twice.

Effects: fail.

withInteger

gizlang
function withInteger(prefix: bytes, n: i64): bytes

PREFIX followed by N's decimal digits, made in one allocation: JavaScript's "k" + i, where appending to a copy of the prefix regrew it digit by digit: writeInteger was 15% of a Map benchmark.

Effects: fail.

writeExactInteger

gizlang
function writeExactInteger(out: mut bytes, n: i64): void

n as a JSON number when a double holds it exactly (|n| <= 2^53 - 1, so JavaScript reads the same value), else as a string of its digits.

Effects: fail.

writeNumber

gizlang
function writeNumber(out: mut bytes, n: f64): void

Writes N as a JSON number, the shortest text that reads back to N; null when N is not finite.

Effects: fail.

reader

gizlang
function reader(text: string): JsonReader

A reader that walks TEXT one value at a time, without building a tree.

Effects: fail.

encode

gizlang
function encode<T>(value: T): string

VALUE as JSON text, as JSON.stringify writes it: a record is an object of its fields in order (an undefined field is left out), a union's case also has its kind, a Vec is an array, a Map<string, V> an object, undefined is null.

encodeIndented

gizlang
function encodeIndented<T>(value: T, indent: i64): string throws JsonError

encode, then laid out as JSON.stringify(value, null, indent) lays it out.

decode

gizlang
function decode<T>(text: string): T throws JsonError

TEXT as a T, as encode writes one; a field the object lacks is an error unless its type takes undefined, and a field the type lacks is skipped.

open

gizlang
function open(out: mut bytes): void

{, before the fields.

Effects: fail.

close

gizlang
function close(out: mut bytes): void

}, after the fields.

Effects: fail.

fieldName

gizlang
function fieldName(out: mut bytes, name: string): void

"NAME":, after a comma unless it is the first field.

Effects: fail.

field

gizlang
function field<T>(out: mut bytes, name: string, value: T): void

The field NAME of VALUE.

optionalField

gizlang
function optionalField<T>(out: mut bytes, name: string, value: Option<T>): void

The field NAME of VALUE, left out when it is undefined, as JSON.stringify leaves it out.

kindField

gizlang
function kindField(out: mut bytes, name: string): void

A union case's "kind":"NAME".

Effects: fail.

writeValue

gizlang
function writeValue<T>(out: mut bytes, value: T): void

VALUE as itself: the case of an untagged union.

expectObject

gizlang
function expectObject(json: Json): void throws JsonError

An error unless JSON is an object.

memberOf

gizlang
function memberOf(json: Json, name: string): Json

The field NAME of the object JSON, or null when it has none.

Effects: fail.

kindOf

gizlang
function kindOf(json: Json): string throws JsonError

The kind of the object JSON: the case of a union.

Effects: fail.

typeofJson

gizlang
function typeofJson(json: Json): string

What TypeScript's typeof says of JSON's value: the case of an untagged union it is.

unknownKind

gizlang
function unknownKind(kind: string): void throws JsonError

The error of a union that has no case KIND.

Effects: fail.

Methods

Json.get

gizlang
function Json.get(self: Json, key: string): Option<Json>

The value under key of an object; none for a missing key or another kind.

Effects: fail.

Json.field

gizlang
function Json.field(self: Json, key: string): Json

The value under key of an object, else null, so a nested read chains: event.field("usage").field("total_tokens").integer().

Effects: fail.

Json.isObject

gizlang
function Json.isObject(self: Json): bool

Whether this is an object.

Json.exactFields

gizlang
function Json.exactFields(self: Json, names: Vec<string>): bool

Exact decoded object fields, without allocating a map or parsing again. Wire schemas still use parseUnique to reject duplicate decoded JSON keys.

Effects: fail.

Json.text

gizlang
function Json.text(self: Json): string

A string's text; "" for another kind.

Json.boolean

gizlang
function Json.boolean(self: Json): bool

A boolean's value; false for another kind.

Json.list

gizlang
function Json.list(self: Json): Vec<Json>

An array's items; none for another kind.

Json.keys

gizlang
function Json.keys(self: Json): Vec<string>

An object's keys, in order; none for another kind.

Json.values

gizlang
function Json.values(self: Json): Vec<Json>

An object's values, in key order; none for another kind.

Json.integer

gizlang
function Json.integer(self: Json): i64

A number toward zero as an integer; 0 for another kind or one past i64's exact range (2^53).

Effects: fail.

Json.booleanOr

gizlang
function Json.booleanOr(self: Json, otherwise: bool): bool

A boolean's value; OTHERWISE for another kind: config.field("lowercase").booleanOr(true).

Json.numberOr

gizlang
function Json.numberOr(self: Json, otherwise: f64): f64

A number's value; OTHERWISE for another kind: config.field("eps").numberOr(1.0e-5).

Json.integerOr

gizlang
function Json.integerOr(self: Json, otherwise: i64): i64

A number toward zero as an integer; OTHERWISE for another kind: config.field("hidden_size").integerOr(768).

Effects: fail.

JsonReader.error

gizlang
function JsonReader.error(self: JsonReader): Option<JsonError>

The first error of the reader, or none.

JsonReader.object

gizlang
function JsonReader.object(self: mut JsonReader): bool

Enters the object at the reader; false (and an error) when the next value is not an object.

Effects: fail.

JsonReader.array

gizlang
function JsonReader.array(self: mut JsonReader): bool

Enters the array at the reader; false (and an error) when the next value is not an array.

Effects: fail.

JsonReader.skip

gizlang
function JsonReader.skip(self: mut JsonReader): void

Skips the next value, with all that it holds.

Effects: fail.

JsonReader.span

gizlang
function JsonReader.span(self: mut JsonReader): Option<JsonSpan>

Validate and consume one value without building its tree or decoding strings. A later typed reader may decode input.slice(span.start, span.end); errors publish no span.

Effects: fail.

JsonReader.key

gizlang
function JsonReader.key(self: mut JsonReader): bool

Moves to the next key of the object; false at its end.

Effects: fail.

JsonReader.keyIs

gizlang
function JsonReader.keyIs(self: JsonReader, key: string): bool

Whether the current key is KEY.

Effects: fail.

JsonReader.keyText

gizlang
function JsonReader.keyText(self: JsonReader): Option<string>

Decode the current validated object key without consuming its value or changing the reader. Empty keys are some(""); no current key or a stopped reader is none. The ordinary string decoder owns all escape semantics.

Effects: fail.

JsonReader.item

gizlang
function JsonReader.item(self: mut JsonReader): bool

Moves to the next item of the array; false at its end.

Effects: fail.

JsonReader.fail

gizlang
function JsonReader.fail(self: mut JsonReader, message: string): void

A decoder's own error (a missing field, a value out of range): it stops the reader like a syntax error, and the first error is the one kept.

JsonReader.number

gizlang
function JsonReader.number(self: mut JsonReader): f64

The next value as a number; 0 and an error when it is not a number.

Effects: fail.

JsonReader.integer

gizlang
function JsonReader.integer(self: mut JsonReader): Option<i64>

A valid decimal integer token in i64's range; no floating point conversion. Fractions, exponents and out-of-range integers are consumed and return none.

Effects: fail.

JsonReader.string

gizlang
function JsonReader.string(self: mut JsonReader): string

The next value as a string; empty and an error when it is not a string.

Effects: fail.

JsonReader.boolean

gizlang
function JsonReader.boolean(self: mut JsonReader): bool

The next value as a boolean; false and an error when it is not a boolean.

Effects: fail.

JsonReader.isNull

gizlang
function JsonReader.isNull(self: mut JsonReader): bool

Probe null: consumes it on a match, leaves other values for a typed read.

Effects: fail.

f64.writeJson

gizlang
function f64.writeJson(self: f64, out: mut bytes): void

Writes the number as JSON.

Effects: fail.

i64.writeJson

gizlang
function i64.writeJson(self: i64, out: mut bytes): void

Writes the integer as JSON.

Effects: fail.

bool.writeJson

gizlang
function bool.writeJson(self: bool, out: mut bytes): void

Writes the boolean as JSON.

Effects: fail.

string.writeJson

gizlang
function string.writeJson(self: string, out: mut bytes): void

Writes the string as JSON, with escapes.

Effects: fail.

Json.writeJson

gizlang
function Json.writeJson(self: Json, out: mut bytes): void

Writes the value as compact JSON.

Effects: fail.

Vec.writeJson

gizlang
function Vec.writeJson<T>(self: Vec<T>, out: mut bytes): void

Writes the vector as a JSON array.

Option.writeJson

gizlang
function Option.writeJson<T>(self: Option<T>, out: mut bytes): void

Writes the value, or null for none.

Map.writeJson

gizlang
function Map.writeJson<V>(self: Map<string, V>, out: mut bytes): void

Writes the map as a JSON object.

f64.readJson

gizlang
function f64.readJson(self: mut f64, json: Json): void throws JsonError

Reads a JSON number. It fails on any other value.

i64.readJson

gizlang
function i64.readJson(self: mut i64, json: Json): void throws JsonError

Reads a JSON number that is an integer. It fails on any other value.

Effects: fail.

bool.readJson

gizlang
function bool.readJson(self: mut bool, json: Json): void throws JsonError

Reads a JSON boolean. It fails on any other value.

string.readJson

gizlang
function string.readJson(self: mut string, json: Json): void throws JsonError

Reads a JSON string. It fails on any other value.

Json.readJson

gizlang
function Json.readJson(self: mut Json, json: Json): void throws JsonError

Takes the JSON value as it is.

Vec.readJson

gizlang
function Vec.readJson<T>(self: mut Vec<T>, json: Json): void throws JsonError

Reads a JSON array, each item as T. It fails on any other value.

Option.readJson

gizlang
function Option.readJson<T>(self: mut Option<T>, json: Json): void throws JsonError

Reads null as none, and any other value as T.

Map.readJson

gizlang
function Map.readJson<V>(self: mut Map<string, V>, json: Json): void throws JsonError

Reads a JSON object, each value as V. It fails on any other value.

Constants

RPC_VERSION

gizlang
const RPC_VERSION = "2.0"

The JSON-RPC version that requests and answers carry.

RPC_PARSE_ERROR

gizlang
const RPC_PARSE_ERROR = -32700

JSON-RPC error: the request is not valid JSON.

RPC_INVALID_REQUEST

gizlang
const RPC_INVALID_REQUEST = -32600

JSON-RPC error: the JSON is not a valid request.

RPC_METHOD_NOT_FOUND

gizlang
const RPC_METHOD_NOT_FOUND = -32601

JSON-RPC error: the method does not exist.

RPC_INVALID_PARAMS

gizlang
const RPC_INVALID_PARAMS = -32602

JSON-RPC error: the parameters are not valid for the method.

RPC_INTERNAL_ERROR

gizlang
const RPC_INTERNAL_ERROR = -32603

JSON-RPC error: the server failed while it ran the method.

MAX_SAFE_INTEGER

gizlang
const MAX_SAFE_INTEGER = 9007199254740991

The greatest integer that a double, and so a JavaScript number, holds exactly.