~/bend-docscommunity

json.bend checks

raw source on the hub · import bend-kit-json@0.5.0.2/json.bend as Json

JSON values, parsed and encoded as RFC 8259. Source: https://github.com/paymog/bend-kit/tree/main/json

2 imports
import Base
import 0x49814d83de8f70993a43e1002be29ecd/bytes.bend as Bytes

Types

type Val source · line 12 · raw

Type

Num keeps the number's exact text, so no precision is lost. Obj keeps its fields in document order, repeated keys included.

type Open source · line 22 · raw

Type

An open container: array items so far, object fields so far, or those fields and the key whose value comes next. Items and fields are reversed.

type W source · line 31 · raw

Type

Writer ------ Octets being written: the buffer, its size in words, the count so far, and the word being filled. Bytes enter at the top of w, as in Bytes.from_string.

type Sb source · line 165 · raw

Type

type Cp source · line 179 · raw

Data

Definitions

def w.room source · line 35 · raw

@grow:Bool -> @buf:Array<U32> -> @+k:U32 -> Array<U32>

The buffer doubles when word k does not fit.

def w.store source · line 42 · raw

@full:Bool -> @buf:Array<U32> -> @+cap:U32 -> @+n:U32 -> @+w:U32 -> W

def w.put source · line 51 · raw

@o:W -> @+b:U32 -> W

def w.shrink source · line 55 · raw

@fit:Bool -> @+n:U32 -> @buf:Array<U32> -> Array<U32>

def w.done source · line 63 · raw

@o:W -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

Stores the last partial word, then copies into the fewest words, as Bytes requires.

def w.cont source · line 72 · raw

@+c:U32 -> @+k:Nat -> U32

def w.cp.of source · line 75 · raw

@+n:U32 -> @+c:U32 -> @o:W -> W

def w.cp source · line 87 · raw

@+c:U32 -> @o:W -> W

One code point in UTF-8.

def w.hex source · line 90 · raw

@+n:U32 -> U32

def w.new source · line 93 · raw

W

def w.of.at source · line 96 · raw

@+len:U32 -> @+cap:U32 -> @r:Pair(Array<U32>, U32) -> W

def w.of source · line 102 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> W

A writer that appends to b.

def w.text source · line 106 · raw

@s:String -> @o:W -> W

def utf8 source · line 114 · raw

@s:String -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

Text, one Char per code point, as UTF-8.

def digit source · line 123 · raw

@+c:U32 -> Bool

def num.trans source · line 126 · raw

@+st:U32 -> @+c:U32 -> U32

def num.accepts source · line 139 · raw

@+st:U32 -> Bool

def hexd source · line 145 · raw

@+c:U32 -> U32

def is_hi source · line 148 · raw

@+v:U32 -> Bool

def is_lo source · line 151 · raw

@+v:U32 -> Bool

def esc.simple source · line 154 · raw

@+e:U32 -> U32

def pk.if source · line 182 · raw

@ok:Bool -> @a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, U32)

def pk source · line 190 · raw

@a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, U32)

Byte i, or 256 at the end, which no rule accepts.

def is_ws source · line 193 · raw

@+c:U32 -> Bool

def plain source · line 197 · raw

@+c:U32 -> Bool

A string byte that needs no check: ASCII, not a control, quote or backslash.

def pos.of source · line 200 · raw

@+i:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Pair(U32, U32))

def pos source · line 205 · raw

@a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, U32))

The offset i and its byte.

def word.go source · line 230 · raw

@w:String -> @ok:Bool -> @r:Pair(Array<U32>, U32) -> @+len:U32 -> @+j:U32 -> Pair(Array<U32>, Bool)

def word source · line 240 · raw

@a:Array<U32> -> @+len:U32 -> @w:String -> @+j:U32 -> Pair(Array<U32>, Bool)

Do the bytes from j spell w?

def hex4.b.go source · line 243 · raw

@n:Nat -> @r:Pair(Array<U32>, U32) -> @+len:U32 -> @+j:U32 -> @+acc:U32 -> Pair(Array<U32>, U32)

def hex4.b source · line 254 · raw

@a:Array<U32> -> @+len:U32 -> @+j:U32 -> Pair(Array<U32>, U32)

Four hex digits from byte j, or 65536 if one is not a hex digit.

def cont source · line 257 · raw

@+b:U32 -> Bool

def utf8.n source · line 261 · raw

@+b0:U32 -> @+b1:U32 -> @+b2:U32 -> @+b3:U32 -> Cp

RFC 3629 §4: overlong forms, surrogates, and code points past U+10FFFF are invalid, width 0.

def utf8.b3 source · line 273 · raw

@+b0:U32 -> @+b1:U32 -> @+b2:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)

def utf8.b2 source · line 277 · raw

@+len:U32 -> @+i:U32 -> @+b0:U32 -> @+b1:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)

def utf8.b1 source · line 281 · raw

@+len:U32 -> @+i:U32 -> @+b0:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)

def utf8.at source · line 286 · raw

@a:Array<U32> -> @+len:U32 -> @+i:U32 -> @+b0:U32 -> Pair(Array<U32>, Cp)

The code point whose lead byte b0 is at i.

def slice.of source · line 289 · raw

@+n:U32 -> @r:Pair(Array<U32>, Array<U32>) -> Pair(Array<U32>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes)

def slice source · line 294 · raw

@+n:U32 -> @+start:U32 -> @a:Array<U32> -> Pair(Array<U32>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes)

The n bytes from start, copied.

def str.b.done source · line 297 · raw

@key:Bool -> @s:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+i:U32 -> @stack:List<&1, Open> -> Sb

def esc.b.lo.if source · line 304 · raw

@ok:Bool -> @+i:U32 -> @+hi:U32 -> @+lo:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> Sb

def esc.b.lo source · line 311 · raw

@+i:U32 -> @+hi:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)

def esc.b.pair source · line 316 · raw

@+len:U32 -> @+i:U32 -> @+hi:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Bool) -> Pair(Array<U32>, Sb)

§8.2: a high surrogate pairs with a following \uDC00-\uDFFF; a lone one is U+FFFD.

def u.class source · line 325 · raw

@+v:U32 -> U32

0: not four hex digits; 1: high surrogate; 2: low surrogate; 3: other.

def esc.b.u.of source · line 328 · raw

@+k:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @+v:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def esc.b.u source · line 339 · raw

@+len:U32 -> @+i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)

def esc.b.one source · line 344 · raw

@+len:U32 -> @+i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)

The escape whose backslash is at i.

def esc.b.cp source · line 353 · raw

@acc:W -> @key:Bool -> @stack:List<&1, Open> -> @+i:U32 -> @r:Pair(Array<U32>, Cp) -> Pair(Array<U32>, Sb)

def esc.b.other source · line 358 · raw

@ascii:Bool -> @+c:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

§7: unescaped chars below U+0020 are not allowed in a string.

def esc.b source · line 366 · raw

@r:Pair(Array<U32>, U32) -> @+len:U32 -> @+i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

A string after its first escape.

def str.b.close source · line 378 · raw

@key:Bool -> @+i:U32 -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Pair(Array<U32>, Sb)

def str.b.esc source · line 382 · raw

@+len:U32 -> @+i:U32 -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Pair(Array<U32>, Sb)

def str.b.cp source · line 386 · raw

@+start:U32 -> @key:Bool -> @stack:List<&1, Open> -> @+i:U32 -> @r:Pair(Array<U32>, Cp) -> Pair(Array<U32>, Sb)

def str.b.other source · line 390 · raw

@ascii:Bool -> @+c:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @+start:U32 -> @key:Bool -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def str.b source · line 398 · raw

@r:Pair(Array<U32>, U32) -> @+len:U32 -> @+i:U32 -> @+start:U32 -> @key:Bool -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

A string whose text so far starts at start and has no escape.

def num.b.fin source · line 410 · raw

@+i:U32 -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes) -> Pair(Array<U32>, Sb)

def num.b.stop source · line 414 · raw

@ok:Bool -> @a:Array<U32> -> @+i:U32 -> @+start:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def num.b.if source · line 421 · raw

@stop:Bool -> @a:Array<U32> -> @+i:U32 -> @+start:U32 -> @+st:U32 -> @+n:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def num.b source · line 428 · raw

@r:Pair(Array<U32>, U32) -> @+i:U32 -> @+start:U32 -> @+st:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def lit.b source · line 433 · raw

@+i:U32 -> @+n:U32 -> @v:Val -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Bool) -> Pair(Array<U32>, Sb)

def value.b source · line 441 · raw

@r:Pair(Array<U32>, U32) -> @+len:U32 -> @+i:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def first.b.end source · line 468 · raw

@open:Open -> @+c:U32 -> @+i:U32 -> @stack:List<&1, Open> -> Sb

After "[" or "{": the closing bracket, or the first item.

def first.b.open source · line 477 · raw

@open:Open -> @+i:U32 -> @stack:List<&1, Open> -> Sb

def first.b source · line 486 · raw

@r:Pair(Array<U32>, U32) -> @+i:U32 -> @open:Open -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def key.b source · line 504 · raw

@r:Pair(Array<U32>, U32) -> @+i:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def colon.b.top source · line 520 · raw

@k:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+i:U32 -> @stack:List<&1, Open> -> Sb

def colon.b source · line 531 · raw

@r:Pair(Array<U32>, U32) -> @k:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @+i:U32 -> @stack:List<&1, Open> -> Pair(Array<U32>, Sb)

def after.b source · line 548 · raw

@v:Val -> @+i:U32 -> @stack:List<&1, Open> -> Sb

A finished value joins its container.

def sep.b.comma source · line 559 · raw

@open:Open -> @+i:U32 -> @up:List<&1, Open> -> Sb

def sep.b.close source · line 568 · raw

@open:Open -> @+c:U32 -> @+i:U32 -> @up:List<&1, Open> -> Sb

def sep.b source · line 578 · raw

@r:Pair(Array<U32>, U32) -> @+i:U32 -> @open:Open -> @up:List<&1, Open> -> Pair(Array<U32>, Sb)

After an item: "," or the closing bracket.

def end.b source · line 594 · raw

@r:Pair(Array<U32>, U32) -> @v:Val -> @+i:U32 -> Pair(Array<U32>, Sb)

def value.r source · line 611 · raw

@+len:U32 -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

A run's end (a, i, c) to each step. The parts bind without + (bendlang/bend#1077).

def first.r source · line 615 · raw

@open:Open -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def key.r source · line 619 · raw

@stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def colon.r source · line 623 · raw

@k:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def str.r source · line 627 · raw

@+len:U32 -> @+s:U32 -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def num.r source · line 631 · raw

@+s:U32 -> @+st:U32 -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def sep.r source · line 635 · raw

@open:Open -> @up:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def end.r source · line 639 · raw

@v:Val -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

def w.span.go source · line 643 · raw

@n:Nat -> @r:Pair(Array<U32>, U32) -> @+i:U32 -> @o:W -> Pair(Array<U32>, W)

def esc.r.go source · line 652 · raw

@+len:U32 -> @+j:U32 -> @c:U32 -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, W) -> Pair(Array<U32>, Sb)

def esc.r source · line 657 · raw

@+len:U32 -> @+i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> @r:Pair(Array<U32>, Pair(U32, U32)) -> Pair(Array<U32>, Sb)

The plain bytes from i to the run's end go onto acc in one loop.

def num.run source · line 662 · raw

@loop:Bool -> @+g:Nat -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, U32))

States 3, 5 and 8 take digits until the number's part ends.

def runb source · line 670 · raw

@+fuel:Nat -> @r:Pair(Array<U32>, Sb) -> @+len:U32 -> Maybe<&1, Val>

fuel: a step eats a byte, or ends a number, a value, or an opening bracket, so 4 * len + 4 steps are enough.

def parse.bytes source · line 703 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Maybe<&1, Val>

One JSON text in UTF-8. None for bad JSON or bad UTF-8 (RFC 8259 §8.1).

def get.pick source · line 710 · raw

@v:Val -> @found:Maybe<&1, Val> -> @r:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Bool)) -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&1, Val>)

def get.step source · line 714 · raw

@k:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @v:Val -> @st:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&1, Val>) -> Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&1, Val>)

def get.go source · line 718 · raw

@kvs:List<&1, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Val)> -> @st:Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Maybe<&1, Val>) -> Maybe<&1, Val>

def get source · line 727 · raw

@v:Val -> @k:String -> Maybe<&1, Val>

§4: the value under key k of an object; the last one when k repeats, as most parsers do.

def at.go source · line 742 · raw

@xs:List<&1, Val> -> @n:Nat -> Maybe<&1, Val>

def at source · line 754 · raw

@v:Val -> @n:Nat -> Maybe<&1, Val>

Item n of an array.

def u32.over source · line 769 · raw

@+acc:U32 -> @+c:U32 -> Bool

def u32.dig source · line 772 · raw

@s:String -> @+acc:U32 -> @bad:Bool -> Maybe<&2, U32>

def u32.zero source · line 783 · raw

@t:String -> Maybe<&2, U32>

def u32.lead source · line 790 · raw

@+c:U32 -> @t:String -> @zero:Bool -> Maybe<&2, U32>

def u32.num source · line 797 · raw

@s:String -> Maybe<&2, U32>

def u32 source · line 805 · raw

@v:Val -> Maybe<&2, U32>

A number that is a whole U32, with no sign, fraction or exponent.

def w.ctl source · line 823 · raw

@ctl:Bool -> @+c:U32 -> @o:W -> W

def w.esc.c source · line 831 · raw

@+c:U32 -> @o:W -> W

§7: quote, backslash and control chars are escaped. Other bytes are already UTF-8.

def w.bytes.go source · line 846 · raw

@n:Nat -> @r:Pair(Array<U32>, U32) -> @+i:U32 -> @o:W -> W

def w.bytes source · line 854 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @o:W -> W

def w.str.go source · line 858 · raw

@n:Nat -> @r:Pair(Array<U32>, U32) -> @+i:U32 -> @o:W -> W

def w.str source · line 867 · raw

@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @o:W -> W

A quoted, escaped string.

def w.lead source · line 872 · raw

@open:Bool -> @+c:U32 -> @o:W -> W

open: the container's first byte comes next; else a comma or its last byte.

def w.close source · line 879 · raw

@open:Bool -> @+a:U32 -> @+z:U32 -> @o:W -> W

def encb.go source · line 886 · raw

@v:Val -> @open:Bool -> @o:W -> W

def encode.bytes source · line 914 · raw

@v:Val -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes

Compact JSON in UTF-8, with object fields in their order.

Templates

template run.cls source · line 208 · raw

@-ok:(@+c:U32 -> Bool) -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Pair(U32, Bool))

template run.go source · line 213 · raw

@-ok:(@+c:U32 -> Bool) -> @g:Nat -> @r:Pair(Array<U32>, Pair(U32, Bool)) -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, U32))

g bounds the loop; it is the parser's fuel, shared, so no count is built per run.

template run source · line 227 · raw

@-ok:(@+c:U32 -> Bool) -> @+g:Nat -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, Pair(U32, U32))

The first offset from i whose byte is not ok, and that byte.