json.bend relies on unsafe/foreign
raw source on the hub · import bend-kit-json@0.5.0.1/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.
NullVal
Flag@on:Bool -> Val
Num@s:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Val
Str@s:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Val
Arr@xs:List<&1, Val> -> Val
Obj@kvs:List<&1, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Val)> -> Val
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.
OArr@xs:List<&1, Val> -> Open
OObj@kvs:List<&1, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Val)> -> Open
OKey@kvs:List<&1, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Val)> -> @key:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Open
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.
W@buf:Array<U32> -> @cap:U32 -> @n:U32 -> @w:U32 -> W
type Sb source · line 165 · raw
Type
BValue@i:U32 -> @stack:List<&1, Open> -> Sb
BFirst@i:U32 -> @open:Open -> @stack:List<&1, Open> -> Sb
BKey@i:U32 -> @stack:List<&1, Open> -> Sb
BColon@key:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> @i:U32 -> @stack:List<&1, Open> -> Sb
BStr@i:U32 -> @start:U32 -> @key:Bool -> @stack:List<&1, Open> -> Sb
BEsc@i:U32 -> @acc:W -> @key:Bool -> @stack:List<&1, Open> -> Sb
BNum@i:U32 -> @start:U32 -> @st:U32 -> @stack:List<&1, Open> -> Sb
BAfter@v:Val -> @i:U32 -> @stack:List<&1, Open> -> Sb
BSep@i:U32 -> @open:Open -> @stack:List<&1, Open> -> Sb
BEnd@v:Val -> @i:U32 -> Sb
BOk@v:Val -> Sb
BFailSb
type Cp source · line 179 · raw
Data
Cp@c:U32 -> @w:U32 -> Cp
type Item source · line 871 · raw
Type
ILit@s:String -> Item
IKey@k:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Item
IVal@v:Val -> Item
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 items.sep source · line 876 · raw
@first:Bool -> @tail:List<&1, Item> -> List<&1, Item>
def items.arr source · line 883 · raw
@xs:List<&1, Val> -> @first:Bool -> @rest:List<&1, Item> -> List<&1, Item>
def items.obj source · line 890 · raw
@kvs:List<&1, Pair(0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes, Val)> -> @first:Bool -> @rest:List<&1, Item> -> List<&1, Item>
def encode.bytes source · line 924 · 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.
Unsafe
unsafe encb.go source · line 900 · raw
@items:List<&1, Item> -> @o:W -> W
ponytail: @unsafe because it walks a work list, not the Val; each step emits text or swaps a container for its strictly smaller parts.