# std/json

The JSON value tree and its canonical writer.

```vyrn
import { Json, JsonField, emit, emitPretty, jsonEq } from "std/json"
import { parseJson } from "std/jsonread"

```

This module imports nothing; the reader, `std/jsonread`, imports it. So a caller that only serializes, such as `toJson`, links no parser. `JNum` holds raw number text and objects keep their stored field order, so `emit` is byte-stable through a parse and generators can depend on the order.

## JsonField

`type`, at line 11.

```vyrn
type JsonField = { key: String, value: Json }
```

## Json

`type`, at line 15.

```vyrn
type Json = enum {
    JNull,
    JBool(Bool),
    JNum(String),
    JStr(String),
    JArr(Array<Json>),
    JObj(Array<JsonField>) }
```

A JSON value. `JNum` holds the raw, validated number text, never a float, so emit -> parse -> emit is byte-stable.

## copyJson

`fn`, at line 65.

```vyrn
fn copyJson(j: Json) -> Json
```

A `Json` that shares nothing with `j`; same as `j.copy()`.

## copyJsonArray

`fn`, at line 119.

```vyrn
fn copyJsonArray(xs: Array<Json>) -> Array<Json>
```

`copy` over a list of values; `xs.copy()` is refused for this element type.

## copyJsonFields

`fn`, at line 128.

```vyrn
fn copyJsonFields(fs: Array<JsonField>) -> Array<JsonField>
```

`copy` over a list of object fields, for the same reason.

## sortKeys

`fn`, at line 139.

```vyrn
fn sortKeys(j: Json) -> Json
```

A copy of the tree with every object's fields in byte order, recursively. Use it for one emission (a diff, content-addressed output); the stored order, which mirrors a `Map`'s insertion order, never moves.

## emit

`fn`, at line 336.

```vyrn
fn emit(j: Json) -> String
```

Emit `j` as compact JSON, field order as stored.

The writers, `copyJson` and `jsonEq` recurse at about two frames a level, so a tree nested past about 450 levels traps at the engine's call cap. `parseJson` refuses input past 128 levels, so only a tree a program builds that deep can reach the cap; bounding it is the program's job.

## emitPretty

`fn`, at line 420.

```vyrn
fn emitPretty(j: Json, indent: Int64) -> String
```

Emit `j` as indented JSON, `indent` spaces per level, field order as stored. Empty arrays and objects stay compact (`[]`, `{}`).

## jsonEq

`fn`, at line 431.

```vyrn
fn jsonEq(a: Json, b: Json) -> Bool
```

Deep structural equality, as equality of canonical emits: `emit` is injective over `Json`, because kinds have distinct delimiters, field order is kept and numbers keep their raw text.

## jsonEncoders

`fn`, at line 439.

```vyrn
gen fn jsonEncoders(t: TypeArg) -> String
```

Writes the encoders `toJson` calls: for each root, the function that renders its value, and for each node, the function that builds its `Json` tree. Generated source cannot spell this module's reserved names, so it writes them as `VyrnRt_` placeholders the compiler folds back.

## JsonReader

`type`, at line 524.

```vyrn
type JsonReader = { src: String, n: Int64, pos: Int64, depth: Int64, err: String }
```

A cursor over one document, which `std/jsonread`'s functions read. It is declared here so that `fromJson`'s generated decoders can name it. `depth` counts the arrays and objects open at `pos`; `err` is the refusal, `""` while there is none.

---

From https://vyrn-lang.github.io/docs/std/json.html — generated by `site/export.vyrn` from the Vyrn repository.
