json.bend relies on unsafe/foreign
raw source on the hub · import bend-kit-json@0.4.0.0/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
Data
Num keeps the number's exact text, so no precision is lost.
NullVal
Flag@on:Bool -> Val
Num@s:String -> Val
Str@s:String -> Val
Arr@xs:List<&2, Val> -> Val
Obj@m:Map<&2, Val> -> Val
type Next source · line 20 · raw
Data
Next@v:Val -> @rest:String -> Next
type Open source · line 25 · raw
Data
An open container: array items so far (reversed), or object fields and the key whose value comes next.
OArr@xs:List<&2, Val> -> Open
OObj@m:Map<&2, Val> -> @key:String -> Open
type St source · line 29 · raw
Data
SValue@s:String -> @stack:List<&2, Open> -> St
SKey@s:String -> @stack:List<&2, Open> -> St
SColon@key:String -> @s:String -> @stack:List<&2, Open> -> St
SStr@s:String -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> St
SAfter@v:Val -> @s:String -> @stack:List<&2, Open> -> St
SDone@v:Val -> @s:String -> St
SFailSt
type Esc source · line 135 · raw
Data
Esc@cp:U32 -> @rest:String -> Esc
type Item source · line 455 · raw
Data
ILit@s:String -> Item
IKey@k:String -> Item
IVal@v:Val -> Item
type Sb source · line 596 · raw
Data
BValue@i:U32 -> @stack:List<&2, Open> -> Sb
BFirst@i:U32 -> @open:Open -> @stack:List<&2, Open> -> Sb
BKey@i:U32 -> @stack:List<&2, Open> -> Sb
BColon@key:String -> @i:U32 -> @stack:List<&2, Open> -> Sb
BStr@i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> Sb
BNum@i:U32 -> @st:U32 -> @acc:String -> @stack:List<&2, Open> -> Sb
BAfter@v:Val -> @i:U32 -> @stack:List<&2, Open> -> Sb
BSep@i:U32 -> @open:Open -> @stack:List<&2, Open> -> Sb
BEnd@v:Val -> @i:U32 -> Sb
BOk@v:Val -> Sb
BFailSb
type Cp source · line 609 · raw
Data
Cp@c:U32 -> @w:U32 -> Cp
type W source · line 980 · raw
Type
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
Definitions
def is_ws source · line 41 · raw
@+c:U32 -> Bool
def ws.go source · line 46 · raw
@t:String -> @+c:U32 -> @ws:Bool -> String
Bool.pick runs both arms, so loops peek: the next char's class is a Bool param and only the matching arm recurses.
def skip_ws source · line 61 · raw
@s:String -> String
def digit source · line 74 · raw
@+c:U32 -> Bool
def num.trans source · line 77 · raw
@+st:U32 -> @+c:U32 -> U32
def num.accepts source · line 90 · raw
@+st:U32 -> Bool
def num.end source · line 93 · raw
@+st:U32 -> @acc:String -> @rest:String -> Maybe<&2, Next>
def num.go source · line 96 · raw
@t:String -> @+c:U32 -> @+st:U32 -> @acc:String -> @stop:Bool -> Maybe<&2, Next>
def num source · line 112 · raw
@s:String -> Maybe<&2, Next>
def lit.if source · line 122 · raw
@+s:String -> @v:Val -> @n:Nat -> @ok:Bool -> Maybe<&2, Next>
def lit source · line 129 · raw
@+s:String -> @word:String -> @v:Val -> @+n:Nat -> Maybe<&2, Next>
def hexd source · line 138 · raw
@+c:U32 -> U32
def hex4.go source · line 141 · raw
@s:String -> @+acc:U32 -> @n:Nat -> Maybe<&2, Esc>
def hex4 source · line 157 · raw
@s:String -> Maybe<&2, Esc>
def is_hi source · line 160 · raw
@+v:U32 -> Bool
def is_lo source · line 163 · raw
@+v:U32 -> Bool
def pair.lo source · line 166 · raw
@+hi:U32 -> @+rest:String -> @lo:Maybe<&2, Esc> -> Esc
def pair source · line 174 · raw
@+hi:U32 -> @+rest:String -> Esc
§8.2: a high surrogate pairs with a following \uDC00-\uDFFF; a lone one is U+FFFD.
def esc.u source · line 177 · raw
@e:Maybe<&2, Esc> -> Maybe<&2, Esc>
def esc.simple source · line 184 · raw
@+e:U32 -> U32
def esc.one source · line 190 · raw
@t:String -> Maybe<&2, Esc>
One escape after the backslash.
def str.esc source · line 198 · raw
@e:Maybe<&2, Esc> -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> St
def str.close source · line 205 · raw
@+acc:String -> @t:String -> @key:Bool -> @stack:List<&2, Open> -> St
def str.c source · line 212 · raw
@quote:Bool -> @ctl:Bool -> @bs:Bool -> @c:U32 -> @t:String -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> St
def str.step source · line 228 · raw
@s:String -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> St
§7: unescaped chars below U+0020 are not allowed in a string.
def got source · line 238 · raw
@m:Maybe<&2, Next> -> @stack:List<&2, Open> -> St
def open.close source · line 245 · raw
@r:String -> @close:Val -> @stack:List<&2, Open> -> @empty:Bool -> @open:Open -> St
def value.step source · line 256 · raw
@+s:String -> @+c:U32 -> @+t:String -> @+stack:List<&2, Open> -> St
def value source · line 266 · raw
@s:String -> @stack:List<&2, Open> -> St
def key source · line 273 · raw
@s:String -> @stack:List<&2, Open> -> St
def colon.top source · line 280 · raw
@k:String -> @r:String -> @stack:List<&2, Open> -> St
def colon source · line 289 · raw
@k:String -> @s:String -> @stack:List<&2, Open> -> St
def after.arr.c source · line 297 · raw
@comma:Bool -> @close:Bool -> @t:String -> @xs:List<&2, Val> -> @up:List<&2, Open> -> St
A finished value joins its container; then "," or the closing bracket.
def after.arr source · line 308 · raw
@xs:List<&2, Val> -> @r:String -> @up:List<&2, Open> -> St
def after.obj.c source · line 315 · raw
@comma:Bool -> @close:Bool -> @t:String -> @m:Map<&2, Val> -> @up:List<&2, Open> -> St
def after.obj source · line 326 · raw
@m:Map<&2, Val> -> @r:String -> @up:List<&2, Open> -> St
def after source · line 333 · raw
@v:Val -> @s:String -> @stack:List<&2, Open> -> St
def step source · line 342 · raw
@st:St -> St
def done source · line 359 · raw
@v:Val -> @rest:String -> Maybe<&2, Val>
def run source · line 367 · raw
@fuel:Nat -> @st:St -> Maybe<&2, Val>
fuel: every step but the last eats at least one char.
def parse source · line 389 · raw
@+s:String -> Maybe<&2, Val>
One JSON text: a value with optional whitespace around it.
def get.hit source · line 395 · raw
@r:Pair(Map<&2, Val>, Bool) -> Bool
def get.some source · line 399 · raw
@r:Pair(Map<&2, Val>, Val) -> Maybe<&2, Val>
def get.has source · line 403 · raw
@+m:Map<&2, Val> -> @+k:String -> @hit:Bool -> Maybe<&2, Val>
def get.of source · line 410 · raw
@+m:Map<&2, Val> -> @+k:String -> Maybe<&2, Val>
def get source · line 414 · raw
@v:Val -> @k:String -> Maybe<&2, Val>
The value under key k of an object.
def hexc source · line 432 · raw
@+n:U32 -> Char
def esc.put source · line 436 · raw
@+c:U32 -> @+acc:String -> String
The escaped form of one char, reversed (it is pushed onto a reversed acc).
def esc.go source · line 445 · raw
@s:String -> @acc:String -> String
def esc source · line 452 · raw
@s:String -> String
def items.sep source · line 460 · raw
@first:Bool -> @tail:List<&2, Item> -> List<&2, Item>
def items.arr source · line 467 · raw
@xs:List<&2, Val> -> @first:Bool -> @rest:List<&2, Item> -> List<&2, Item>
def items.obj source · line 474 · raw
@kvs:List<&2, Sigma<&2, &2, String, _ => Val>> -> @first:Bool -> @rest:List<&2, Item> -> List<&2, Item>
def put source · line 481 · raw
@s:String -> @racc:String -> String
def encode source · line 511 · raw
@v:Val -> String
Compact JSON; object keys come out sorted.
def at.go source · line 514 · raw
@xs:List<&2, Val> -> @n:Nat -> Maybe<&2, Val>
def at source · line 526 · raw
@v:Val -> @n:Nat -> Maybe<&2, Val>
def u32.over source · line 541 · raw
@+acc:U32 -> @+c:U32 -> Bool
def u32.dig source · line 544 · raw
@s:String -> @+acc:U32 -> @bad:Bool -> Maybe<&2, U32>
def u32.zero source · line 555 · raw
@t:String -> Maybe<&2, U32>
def u32.lead source · line 562 · raw
@+c:U32 -> @t:String -> @zero:Bool -> Maybe<&2, U32>
def u32.num source · line 569 · raw
@s:String -> Maybe<&2, U32>
def u32 source · line 576 · raw
@v:Val -> Maybe<&2, U32>
def pk.if source · line 612 · raw
@ok:Bool -> @a:Array<U32> -> @+i:U32 -> Pair(Array<U32>, U32)
def pk source · line 620 · raw
@a:Array<U32> -> @+len:U32 -> @+i:U32 -> Pair(Array<U32>, U32)
Byte i, or 256 at the end, which no rule accepts.
def word.go source · line 623 · raw
@w:String -> @ok:Bool -> @r:Pair(Array<U32>, U32) -> @+len:U32 -> @+j:U32 -> Pair(Array<U32>, Bool)
def word source · line 633 · 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 636 · raw
@n:Nat -> @r:Pair(Array<U32>, U32) -> @+len:U32 -> @+j:U32 -> @+acc:U32 -> Pair(Array<U32>, U32)
def hex4.b source · line 647 · 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 650 · raw
@+b:U32 -> Bool
def utf8.n source · line 654 · 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 666 · raw
@+b0:U32 -> @+b1:U32 -> @+b2:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.b2 source · line 670 · raw
@+len:U32 -> @+i:U32 -> @+b0:U32 -> @+b1:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.b1 source · line 674 · raw
@+len:U32 -> @+i:U32 -> @+b0:U32 -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Cp)
def utf8.at source · line 679 · 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 str.b.cp source · line 682 · raw
@acc:String -> @key:Bool -> @stack:List<&2, Open> -> @+i:U32 -> @r:Pair(Array<U32>, Cp) -> Pair(Array<U32>, Sb)
def str.b.lo source · line 686 · raw
@+i:U32 -> @+hi:U32 -> @+acc:String -> @+key:Bool -> @+stack:List<&2, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)
def str.b.pair source · line 691 · raw
@+len:U32 -> @+i:U32 -> @+hi:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, 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 700 · raw
@+v:U32 -> U32
0: not four hex digits; 1: high surrogate; 2: low surrogate; 3: other.
def str.b.u.of source · line 703 · raw
@+k:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @+v:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def str.b.u source · line 714 · raw
@+len:U32 -> @+i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)
def str.b.esc source · line 719 · raw
@+len:U32 -> @+i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> @r:Pair(Array<U32>, U32) -> Pair(Array<U32>, Sb)
The escape whose backslash is at i.
def str.b.close source · line 728 · raw
@+i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> Sb
def str.b.other source · line 736 · raw
@ascii:Bool -> @+c:U32 -> @a:Array<U32> -> @+len:U32 -> @+i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
§7: unescaped chars below U+0020 are not allowed in a string.
def str.b source · line 743 · raw
@r:Pair(Array<U32>, U32) -> @+len:U32 -> @+i:U32 -> @acc:String -> @key:Bool -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def num.b.end source · line 755 · raw
@ok:Bool -> @+i:U32 -> @acc:String -> @stack:List<&2, Open> -> Sb
def num.b.if source · line 762 · raw
@stop:Bool -> @+c:U32 -> @+i:U32 -> @+st:U32 -> @+n:U32 -> @acc:String -> @stack:List<&2, Open> -> Sb
def num.b source · line 769 · raw
@r:Pair(Array<U32>, U32) -> @+i:U32 -> @+st:U32 -> @acc:String -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def lit.b source · line 774 · raw
@+i:U32 -> @+n:U32 -> @v:Val -> @stack:List<&2, Open> -> @r:Pair(Array<U32>, Bool) -> Pair(Array<U32>, Sb)
def value.b source · line 782 · raw
@r:Pair(Array<U32>, U32) -> @+len:U32 -> @+i:U32 -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def first.b.end source · line 809 · raw
@open:Open -> @+c:U32 -> @+i:U32 -> @stack:List<&2, Open> -> Sb
After "[" or "{": the closing bracket, or the first item.
def first.b.open source · line 816 · raw
@open:Open -> @+i:U32 -> @stack:List<&2, Open> -> Sb
def first.b source · line 823 · raw
@r:Pair(Array<U32>, U32) -> @+i:U32 -> @open:Open -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def key.b source · line 841 · raw
@r:Pair(Array<U32>, U32) -> @+i:U32 -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def colon.b.top source · line 857 · raw
@k:String -> @+i:U32 -> @stack:List<&2, Open> -> Sb
def colon.b source · line 866 · raw
@r:Pair(Array<U32>, U32) -> @k:String -> @+i:U32 -> @stack:List<&2, Open> -> Pair(Array<U32>, Sb)
def after.b source · line 883 · raw
@v:Val -> @+i:U32 -> @stack:List<&2, Open> -> Sb
A finished value joins its container.
def sep.b.comma source · line 892 · raw
@open:Open -> @+i:U32 -> @up:List<&2, Open> -> Sb
def sep.b.close source · line 899 · raw
@open:Open -> @+c:U32 -> @+i:U32 -> @up:List<&2, Open> -> Sb
def sep.b source · line 907 · raw
@r:Pair(Array<U32>, U32) -> @+i:U32 -> @open:Open -> @up:List<&2, Open> -> Pair(Array<U32>, Sb)
After an item: "," or the closing bracket.
def end.b source · line 923 · raw
@r:Pair(Array<U32>, U32) -> @v:Val -> @+i:U32 -> Pair(Array<U32>, Sb)
def runb source · line 940 · raw
@fuel:Nat -> @r:Pair(Array<U32>, Sb) -> @+len:U32 -> Maybe<&2, 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 971 · raw
@b:0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes -> Maybe<&2, Val>
One JSON text in UTF-8. None for bad JSON or bad UTF-8 (RFC 8259 §8.1).
def w.room source · line 984 · raw
@grow:Bool -> @buf:Array<U32> -> @+k:U32 -> Array<U32>
The buffer doubles when word k does not fit.
def w.store source · line 991 · raw
@full:Bool -> @buf:Array<U32> -> @+cap:U32 -> @+n:U32 -> @+w:U32 -> W
def w.put source · line 1000 · raw
@o:W -> @+b:U32 -> W
def w.shrink source · line 1004 · raw
@fit:Bool -> @+n:U32 -> @buf:Array<U32> -> Array<U32>
def w.done source · line 1012 · 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 1021 · raw
@+c:U32 -> @+k:Nat -> U32
def w.cp.of source · line 1024 · raw
@+n:U32 -> @+c:U32 -> @o:W -> W
def w.cp source · line 1036 · raw
@+c:U32 -> @o:W -> W
One code point in UTF-8.
def w.hex source · line 1039 · raw
@+n:U32 -> U32
def w.ctl source · line 1042 · raw
@ctl:Bool -> @+c:U32 -> @o:W -> W
def w.esc.c source · line 1050 · raw
@+c:U32 -> @o:W -> W
§7: quote, backslash and control chars are escaped.
def w.text source · line 1065 · raw
@s:String -> @o:W -> W
def w.str.go source · line 1073 · raw
@s:String -> @o:W -> W
A quoted, escaped string.
def w.str source · line 1080 · raw
@s:String -> @o:W -> W
def encode.bytes source · line 1109 · raw
@v:Val -> 0x49814d83de8f70993a43e1002be29ecd/bytes.Bytes
encode, as UTF-8 in Bytes.
Unsafe
unsafe enc.go source · line 487 · raw
@items:List<&2, Item> -> @racc:String -> String
ponytail: @unsafe because it walks a work list, not the Val; each step emits text or swaps a container for its strictly smaller parts.
unsafe encb.go source · line 1085 · raw
@items:List<&2, Item> -> @o:W -> W
ponytail: @unsafe for the same reason as enc.go.