2e(2-3): Print & Parse JSON

++json:html

Container core for JSON decoding/encoding functions.

++en:json:html

Print json

Encode jon, a json structure, in a cord.

Accepts

jon is any json.

Produces

A cord.

Source

Click to expand

++ en :: encode JSON to tape
~% %en +>+ ~
|^ |= jon=^json
^- cord
(rap 3 (flop (onto jon ~)))
:: :: ++onto:en:json:html
++ onto
|= [val=^json out=(list @t)]
^+ out
?~ val ['null' out]
?- -.val
%a
?~ p.val ['[]' out]
=. out ['[' out]
!.
|- ^+ out
=. out ^$(val i.p.val)
?~(t.p.val [']' out] $(p.val t.p.val, out [',' out]))
::
%b
[?:(p.val 'true' 'false') out]
::
%n
[p.val out]
::
%s
[(scap p.val) out]
::
%o
=/ viz ~(tap by p.val)
?~ viz ['{}' out]
=. out ['{' out]
!.
|- ^+ out
=. out ^$(val q.i.viz, out [':' [(scap p.i.viz) out]])
?~(t.viz ['}' out] $(viz t.viz, out [',' out]))
==
:: :: ++scap:en:json:html
++ scap
|= val=@t
^- @t
=/ out=(list @t) ['"' ~]
=/ len (met 3 val)
=| [i=@ud pos=@ud]
|- ^- @t
?: =(len i)
(rap 3 (flop ['"' (rsh [3 pos] val) out]))
=/ car (cut 3 [i 1] val)
?: ?& (gth car 0x1f)
!=(car 0x22)
!=(car 0x5C)
!=(car 0x7F)
==
$(i +(i))
=/ cap
?+ car (crip '\\' 'u' ((x-co 4):co car))
%10 '\\n'
%'"' '\\"'
%'\\' '\\\\'
==
$(i +(i), pos +(i), out [cap (cut 3 [pos (sub i pos)] val) out])
-- ::en

Examples

> (en:json:html s+'foo')
'"foo"'
> (en:json:html o+(malt (limo ~[['foo' s+'xxx'] ['bar' n+'123'] ['baz' b+&]])))
'{"foo":"xxx","baz":true,"bar":123}'

++de:json:html

Parse json

Decode txt, a cord of stringified JSON, to a (unit json) which is null if parsing failed.

Accepts

txt is a cord.

Produces

A (unit json).

Source

Click to expand

++ de :: parse cord to JSON
~% %de +>+ ~
|^ |= txt=cord
^- (unit ^json)
(rush txt apex)
:: :: ++abox:de-json:html
++ abox :: array
%+ stag %a
(ifix [sel (wish ser)] (more (wish com) apex))
:: :: ++apex:de-json:html
++ apex :: any value
%+ knee *^json |. ~+
%+ ifix [spac spac]
;~ pose
(cold ~ (jest 'null'))
(stag %b bool)
(stag %s stri)
(cook |=(s=tape [%n p=(rap 3 s)]) numb)
abox
obox
==
:: :: ++bool:de-json:html
++ bool :: boolean
;~ pose
(cold & (jest 'true'))
(cold | (jest 'false'))
==
:: :: ++esca:de-json:html
++ esca :: escaped character
;~ pfix bas
=* loo
=* lip
^- (list (pair @t @))
[b+8 t+9 n+10 f+12 r+13 ~]
=* wow
^~
^- (map @t @)
(malt lip)
(sear ~(get by wow) low)
;~(pose doq fas bas loo unic)
==
:: :: ++expo:de-json:html
++ expo :: exponent
;~ (comp weld)
(piec (mask "eE"))
(mayb (piec (mask "+-")))
(plus nud)
==
:: :: ++frac:de-json:html
++ frac :: fraction
;~(plug dot (plus nud))
:: :: ++jcha:de-json:html
++ jcha :: string character
;~(pose ;~(less doq bas (shim 32 255)) esca)
:: :: ++mayb:de-json:html
++ mayb :: optional
|*(bus=rule ;~(pose bus (easy ~)))
:: :: ++numb:de-json:html
++ numb :: number
;~ (comp weld)
(mayb (piec hep))
;~ pose
(piec (just '0'))
;~(plug (shim '1' '9') (star nud))
==
(mayb frac)
(mayb expo)
==
:: :: ++obje:de-json:html
++ obje :: object list
%+ ifix [(wish kel) (wish ker)]
(more (wish com) pear)
:: :: ++obox:de-json:html
++ obox :: object
(stag %o (cook malt obje))
:: :: ++pear:de-json:html
++ pear :: key-value
;~(plug ;~(sfix (wish stri) (wish col)) apex)
:: :: ++piec:de-json:html
++ piec :: listify
|* bus=rule
(cook |=(a=@ [a ~]) bus)
:: :: ++stri:de-json:html
++ stri :: string
%+ sear
|= a=cord
?. (sune a) ~
(some a)
(cook crip (ifix [doq doq] (star jcha)))
:: :: ++spac:de-json:html
++ spac :: whitespace
(star (mask [`@`9 `@`10 `@`13 ' ' ~]))
:: :: ++unic:de-json:html
++ unic :: escaped UTF16
=* lob 0x0
=* hsb 0xd800
=* lsb 0xdc00
=* hib 0xe000
=* hil 0x1.0000
|^
%+ cook
|= a=@
^- @t
(tuft a)
;~ pfix (just 'u')
;~(pose solo pair)
==
++ quad :: parse num from 4 hex
(bass 16 (stun [4 4] hit))
++ meat :: gen gate for sear:
|= [bot=@ux top=@ux flp=?] :: accept num in range,
|= sur=@ux :: optionally reduce
^- (unit @)
?. &((gte sur bot) (lth sur top))
~
%- some
?. flp sur
(sub sur bot)
++ solo :: single valid UTF16
;~ pose
(sear (meat lob hsb |) quad)
(sear (meat hib hil |) quad)
==
++ pair :: UTF16 surrogate pair
%+ cook
|= [hig=@ low=@]
^- @t
:(add hil low (lsh [1 5] hig))
;~ plug
(sear (meat hsb lsb &) quad)
;~ pfix (jest '\\u')
(sear (meat lsb hib &) quad)
==
==
--
:: :: ++utfe:de-json:html
++ utfe :: UTF-8 sequence
;~ less doq bas
=* qua
%+ cook
|= [a=@ b=@ c=@ d=@]
(rap 3 a b c d ~)
;~ pose
;~ plug
(shim 241 243)
(shim 128 191)
(shim 128 191)
(shim 128 191)
==
;~ plug
(just '\F0')
(shim 144 191)
(shim 128 191)
(shim 128 191)
==
;~ plug
(just '\F4')
(shim 128 143)
(shim 128 191)
(shim 128 191)
==
==
=* tre
%+ cook
|= [a=@ b=@ c=@]
(rap 3 a b c ~)
;~ pose
;~ plug
;~ pose
(shim 225 236)
(shim 238 239)
==
(shim 128 191)
(shim 128 191)
==
;~ plug
(just '\E0')
(shim 160 191)
(shim 128 191)
==
;~ plug
(just '\ED')
(shim 128 159)
(shim 128 191)
==
==
=* dos
%+ cook
|= [a=@ b=@]
(cat 3 a b)
;~ plug
(shim 194 223)
(shim 128 191)
==
;~(pose qua tre dos)
==
:: :: ++wish:de-json:html
++ wish :: with whitespace
|*(sef=rule ;~(pfix spac sef))
:: XX: These gates should be moved to hoon.hoon
:: :: ++sune:de-json:html
++ sune :: cord UTF-8 sanity
|= b=@t
^- ?
?: =(0 b) &
?. (sung b) |
$(b (rsh [3 (teff b)] b))
:: :: ++sung:de-json:html
++ sung :: char UTF-8 sanity
|^ |= b=@t
^- ?
=+ len=(teff b)
?: =(4 len) (quad b)
?: =(3 len) (tres b)
?: =(2 len) (dos b)
(lte (end 3 b) 127)
::
++ dos
|= b=@t
^- ?
=+ :- one=(cut 3 [0 1] b)
two=(cut 3 [1 1] b)
?& (rang one 194 223)
(cont two)
==
::
++ tres
|= b=@t
^- ?
=+ :+ one=(cut 3 [0 1] b)
two=(cut 3 [1 1] b)
tre=(cut 3 [2 1] b)
?&
?|
?& |((rang one 225 236) (rang one 238 239))
(cont two)
==
::
?& =(224 one)
(rang two 160 191)
==
::
?& =(237 one)
(rang two 128 159)
==
==
::
(cont tre)
==
::
++ quad
|= b=@t
^- ?
=+ :^ one=(cut 3 [0 1] b)
two=(cut 3 [1 1] b)
tre=(cut 3 [2 1] b)
for=(cut 3 [3 1] b)
?&
?|
?& (rang one 241 243)
(cont two)
==
::
?& =(240 one)
(rang two 144 191)
==
::
?& =(244 one)
(rang two 128 143)
==
==
::
(cont tre)
(cont for)
==
::
++ cont
|= a=@
^- ?
(rang a 128 191)
::
++ rang
|= [a=@ bot=@ top=@]
^- ?
?> (lte bot top)
&((gte a bot) (lte a top))
--
:: XX: This +teff should overwrite the existing +teff
:: :: ++teff:de-json:html
++ teff :: UTF-8 length
|= a=@t
^- @
=+ b=(end 3 a)
?: =(0 b)
?> =(`@`0 a) 0
?: (lte b 127) 1
?: (lte b 223) 2
?: (lte b 239) 3
4
-- ::de

Examples

> (de:json:html '"foo"')
[~ [%s p='foo']]
> (de:json:html '{"foo":"xxx","baz":true,"bar":123}')
[ ~
[ %o
p
[ n=[p='baz' q=[%b p=%.y]]
l=[n=[p='bar' q=[%n p=~.123]] l={} r={}]
r=[n=[p='foo' q=[%s p='xxx']] l={} r={}]
]
]
]

++en-json:html

Print json

Deprecated: use ++en:json:html instead.

Encode val, a json structure, in a tape.

Accepts

val is any json.

Produces

A tape.

Source

++ en-json
|= jon=^json
^- tape
(trip (en:json jon))

Examples

> (en-json:html s+'foo')
"\"foo\""
> (en-json:html o+(malt (limo ~[['foo' s+'xxx'] ['bar' n+'123'] ['baz' b+&]])))
"\{\"foo\":\"xxx\",\"baz\":true,\"bar\":123}"

++de-json:html

Parse json

Deprecated: use ++de:json:html instead.

Parse cord a to a json structure. The result is wrapped in a unit which is null if parsing failed.

Accepts

a is a cord in which JSON is encoded.

Produces

A (unit json). The unit is ~ if parsing failed.

Source

++ en-json
|= jon=^json
^- tape
(trip (en:json jon))

Examples

> (de-json:html '{"foo":"xxx","baz":true,"bar":123}')
[~ [%o p={[p='bar' q=[%n p=~.123]] [p='baz' q=[%b p=%.y]] [p='foo' q=[%s p='xxx']]}]]
> (de-json:html '"foo"')
[~ [%s p='foo']]