src/json.bend
bend-toon-codec@0.1.0.0 · 113 lines · 13 definitions
1import Base
2import bend-toon-codec@0.1.0.0/src/num.bend as N
3
4
5
6
7
8
9
10
11
12
13
14
15
16type Json is Data:
17 JNull{}
18 JBool{b: Bool}
19 JNum{text: String}
20 JStr{s: String}
21 JArr{items: Json}
22 JObj{fields: Json}
23 JNil{}
24 JCons{head: Json, tail: Json}
25 JField{key: String, val: Json, tail: Json}
26
27
28def arr.chain(+xs: List<&2, Json>) -> Json:
29 match xs:
30 case Nil{}:
31 JNil{}
32 case Con{h, t}:
33 JCons{h, arr.chain(t)}
34
35def arr(+xs: List<&2, Json>) -> Json:
36 JArr{arr.chain(xs)}
37
38def field.of(kv: String & Json, +rest: Json) -> Json:
39 (k, v) = kv
40 JField{k, v, rest}
41
42def obj.chain(kvs: List<(String & Json)>) -> Json:
43 match kvs:
44 case Nil{}:
45 JNil{}
46 case Con{kv, t}:
47 field.of(kv, obj.chain(t))
48
49
50def obj(kvs: List<(String & Json)>) -> Json:
51 JObj{obj.chain(kvs)}
52
53
54def num(+t: String) -> Json:
55 JNum{t}
56
57def str(+s: String) -> Json:
58 JStr{s}
59
60
61
62def num.eq(+a: Maybe<&2, String>, +b: Maybe<&2, String>) -> Bool:
63 match a b:
64 case Some{x} Some{y}:
65 String.eq(x, y)
66 case None{} None{}:
67 True{}
68 case _ _:
69 False{}
70
71def bool.eq(+a: Bool, +b: Bool) -> Bool:
72 match a b:
73 case True{} True{}:
74 True{}
75 case False{} False{}:
76 True{}
77 case _ _:
78 False{}
79
80def lit.eq(+a: Json, +b: Json) -> Bool:
81 match a b:
82 case JNull{} JNull{}:
83 True{}
84 case JBool{x} JBool{y}:
85 bool.eq(x, y)
86 case JNil{} JNil{}:
87 True{}
88 case _ _:
89 False{}
90
91def prim.eq(+a: Json, +b: Json) -> Bool:
92 match a b:
93 case JNum{x} JNum{y}:
94 num.eq(N.canon(x), N.canon(y))
95 case JStr{x} JStr{y}:
96 String.eq(x, y)
97 case _ _:
98 lit.eq(a, b)
99
100
101
102def eq(+a: Json, +b: Json) -> Bool:
103 match a b:
104 case JArr{x} JArr{y}:
105 eq(x, y)
106 case JObj{x} JObj{y}:
107 eq(x, y)
108 case JCons{h, t} JCons{h2, t2}:
109 eq(h, h2) && eq(t, t2)
110 case JField{k, v, t} JField{k2, v2, t2}:
111 String.eq(k, k2) && eq(v, v2) && eq(t, t2)
112 case _ _:
113 prim.eq(a, b)