src/pbjson.bend
bendonnect-rpc@0.1.0.0 · 750 lines · 163 definitions
1
2
3
4
5
6
7
8import Base
9import bend-kit-bytes@0.3.2.0/bytes.bend as Bytes
10import bend-kit-encoding@0.4.0.0/encoding.bend as Enc
11import bend-kit-json@0.6.1.1/json.bend as Json
12import bend-kit-protobuf@0.1.0.0/protobuf.bend as Pb
13import bendonnect-rpc@0.1.0.0/src/b64.bend as B64
14import bendonnect-rpc@0.1.0.0/src/pb.bend as Pbr
15
16
17
18def i32.show(+x: U32) -> String:
19 Bool.pick(String, U32.is_ge(x, 2147483648), String.append("-", U32.show((0 - x : U32))), U32.show(x))
20
21def num(+s: String) -> Json.Val:
22 Json.Num{Bytes.from_string(s)}
23
24def str(+s: String) -> Json.Val:
25 Json.Str{Enc.utf8.encode(s)}
26
27
28def f32.fin(kind: U32, +f: F32) -> Json.Val:
29 match kind:
30 case 0:
31 num(F32.show(f))
32 case 1:
33 str("NaN")
34 case 2:
35 str("Infinity")
36 case _:
37 str("-Infinity")
38
39def f32.kind(+b: U32) -> U32:
40 Bool.pick(U32, U32.is_ne(((b >> 23n) .&. 255 : U32), 255), 0,
41 Bool.pick(U32, U32.is_ne((b .&. 8388607 : U32), 0), 1,
42 Bool.pick(U32, U32.is_zero((b >> 31n : U32)), 2, 3)))
43
44
45
46def val.double(+f: F32) -> Json.Val:
47 f32.fin(f32.kind(F32.bits(f)), f)
48
49def val.float(+f: F32) -> Json.Val:
50 f32.fin(f32.kind(F32.bits(f)), f)
51
52def val.int32(+x: U32) -> Json.Val:
53 num(i32.show(x))
54
55def val.sint32(+x: U32) -> Json.Val:
56 num(i32.show(x))
57
58def val.sfixed32(+x: U32) -> Json.Val:
59 num(i32.show(x))
60
61def val.uint32(+x: U32) -> Json.Val:
62 num(U32.show(x))
63
64def val.fixed32(+x: U32) -> Json.Val:
65 num(U32.show(x))
66
67
68def val.int64(+w: Pb.Word64) -> Json.Val:
69 str(Pbr.word64.show_s(w))
70
71def val.sint64(+w: Pb.Word64) -> Json.Val:
72 str(Pbr.word64.show_s(w))
73
74def val.sfixed64(+w: Pb.Word64) -> Json.Val:
75 str(Pbr.word64.show_s(w))
76
77def val.uint64(+w: Pb.Word64) -> Json.Val:
78 str(Pbr.word64.show_u(w))
79
80def val.fixed64(+w: Pb.Word64) -> Json.Val:
81 str(Pbr.word64.show_u(w))
82
83def val.bool(+b: Bool) -> Json.Val:
84 Json.Flag{b}
85
86def val.string(+s: String) -> Json.Val:
87 str(s)
88
89
90def val.bytes(+xs: List<&2, U32>) -> Json.Val:
91 str(B64.encode_std(Pbr.bytes.of_list(xs)))
92
93
94def val.enum.go(+s: String, +x: U32) -> Json.Val:
95 Bool.pick(Json.Val, String.is_empty(s), num(i32.show(x)), str(s))
96
97def val.enum(~name: @+n: U32 -> String, +x: U32) -> Json.Val:
98 val.enum.go(name(x), x)
99
100
101
102def entry(+key: String, v: Json.Val) -> Bytes.Bytes & Json.Val:
103 (Enc.utf8.encode(key), v)
104
105def put.always.v(+name: String, v: Json.Val, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
106 Con{entry(name, v), acc}
107
108def put.skip(skip: Bool, +name: String, v: Json.Val, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
109 match skip:
110 case True{}:
111 acc
112 case False{}:
113 put.always.v(name, v, acc)
114
115
116def obj(acc: List<&1, Bytes.Bytes & Json.Val>) -> Json.Val:
117 Json.Obj{List.reverse(&1, Bytes.Bytes & Json.Val, acc)}
118
119
120def put.double.always(+name: String, +f: F32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
121 put.always.v(name, val.double(f), acc)
122
123def put.float.always(+name: String, +f: F32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
124 put.always.v(name, val.float(f), acc)
125
126def put.int32.always(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
127 put.always.v(name, val.int32(x), acc)
128
129def put.sint32.always(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
130 put.always.v(name, val.sint32(x), acc)
131
132def put.sfixed32.always(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
133 put.always.v(name, val.sfixed32(x), acc)
134
135def put.uint32.always(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
136 put.always.v(name, val.uint32(x), acc)
137
138def put.fixed32.always(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
139 put.always.v(name, val.fixed32(x), acc)
140
141def put.int64.always(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
142 put.always.v(name, val.int64(w), acc)
143
144def put.sint64.always(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
145 put.always.v(name, val.sint64(w), acc)
146
147def put.sfixed64.always(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
148 put.always.v(name, val.sfixed64(w), acc)
149
150def put.uint64.always(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
151 put.always.v(name, val.uint64(w), acc)
152
153def put.fixed64.always(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
154 put.always.v(name, val.fixed64(w), acc)
155
156def put.bool.always(+name: String, +b: Bool, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
157 put.always.v(name, val.bool(b), acc)
158
159def put.string.always(+name: String, +s: String, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
160 put.always.v(name, val.string(s), acc)
161
162def put.bytes.always(+name: String, +xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
163 put.always.v(name, val.bytes(xs), acc)
164
165def put.enum.always(~name: @+n: U32 -> String, +jn: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
166 put.always.v(jn, val.enum(~name, x), acc)
167
168
169def put.message(+name: String, v: Json.Val, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
170 put.always.v(name, v, acc)
171
172
173def put.double(+name: String, +f: F32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
174 put.skip(U32.is_zero(F32.bits(f)), name, val.double(f), acc)
175
176def put.float(+name: String, +f: F32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
177 put.skip(U32.is_zero(F32.bits(f)), name, val.float(f), acc)
178
179def put.int32(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
180 put.skip(U32.is_zero(x), name, val.int32(x), acc)
181
182def put.sint32(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
183 put.skip(U32.is_zero(x), name, val.sint32(x), acc)
184
185def put.sfixed32(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
186 put.skip(U32.is_zero(x), name, val.sfixed32(x), acc)
187
188def put.uint32(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
189 put.skip(U32.is_zero(x), name, val.uint32(x), acc)
190
191def put.fixed32(+name: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
192 put.skip(U32.is_zero(x), name, val.fixed32(x), acc)
193
194def put.int64(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
195 put.skip(Pb.Word64.is_zero(w), name, val.int64(w), acc)
196
197def put.sint64(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
198 put.skip(Pb.Word64.is_zero(w), name, val.sint64(w), acc)
199
200def put.sfixed64(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
201 put.skip(Pb.Word64.is_zero(w), name, val.sfixed64(w), acc)
202
203def put.uint64(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
204 put.skip(Pb.Word64.is_zero(w), name, val.uint64(w), acc)
205
206def put.fixed64(+name: String, +w: Pb.Word64, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
207 put.skip(Pb.Word64.is_zero(w), name, val.fixed64(w), acc)
208
209def put.bool(+name: String, +b: Bool, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
210 put.skip(Bool.not(b), name, val.bool(b), acc)
211
212def put.string(+name: String, +s: String, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
213 put.skip(String.is_empty(s), name, val.string(s), acc)
214
215def put.bytes(+name: String, +xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
216 put.skip(List.is_empty(&2, U32, xs), name, val.bytes(xs), acc)
217
218def put.enum(~name: @+n: U32 -> String, +jn: String, +x: U32, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
219 put.skip(U32.is_zero(x), jn, val.enum(~name, x), acc)
220
221
222
223def rep.arr(~T: Data, ~val: @+x: T -> Json.Val, xs: List<&2, T>) -> List<&1, Json.Val>:
224 match xs:
225 case Nil{}:
226 Nil{}
227 case Con{h, t}:
228 val(h) <> rep.arr(~T, ~val, t)
229
230def rep.put(~T: Data, ~val: @+x: T -> Json.Val, +name: String, xs: List<&2, T>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
231 match xs:
232 case Nil{}:
233 acc
234 case Con{h, t}:
235 put.always.v(name, Json.Arr{rep.arr(~T, ~val, Con{h, t})}, acc)
236
237def put.repeated.double(+name: String, xs: List<&2, F32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
238 rep.put(~F32, ~val.double, name, xs, acc)
239
240def put.repeated.float(+name: String, xs: List<&2, F32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
241 rep.put(~F32, ~val.float, name, xs, acc)
242
243def put.repeated.int32(+name: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
244 rep.put(~U32, ~val.int32, name, xs, acc)
245
246def put.repeated.sint32(+name: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
247 rep.put(~U32, ~val.sint32, name, xs, acc)
248
249def put.repeated.sfixed32(+name: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
250 rep.put(~U32, ~val.sfixed32, name, xs, acc)
251
252def put.repeated.uint32(+name: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
253 rep.put(~U32, ~val.uint32, name, xs, acc)
254
255def put.repeated.fixed32(+name: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
256 rep.put(~U32, ~val.fixed32, name, xs, acc)
257
258def put.repeated.int64(+name: String, xs: List<&2, Pb.Word64>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
259 rep.put(~Pb.Word64, ~val.int64, name, xs, acc)
260
261def put.repeated.sint64(+name: String, xs: List<&2, Pb.Word64>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
262 rep.put(~Pb.Word64, ~val.sint64, name, xs, acc)
263
264def put.repeated.sfixed64(+name: String, xs: List<&2, Pb.Word64>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
265 rep.put(~Pb.Word64, ~val.sfixed64, name, xs, acc)
266
267def put.repeated.uint64(+name: String, xs: List<&2, Pb.Word64>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
268 rep.put(~Pb.Word64, ~val.uint64, name, xs, acc)
269
270def put.repeated.fixed64(+name: String, xs: List<&2, Pb.Word64>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
271 rep.put(~Pb.Word64, ~val.fixed64, name, xs, acc)
272
273def put.repeated.bool(+name: String, xs: List<&2, Bool>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
274 rep.put(~Bool, ~val.bool, name, xs, acc)
275
276def put.repeated.string(+name: String, xs: List<&2, String>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
277 rep.put(~String, ~val.string, name, xs, acc)
278
279def put.repeated.bytes(+name: String, xs: List<&2, List<&2, U32>>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
280 rep.put(~List<&2, U32>, ~val.bytes, name, xs, acc)
281
282def put.repeated.enum(~name: @+n: U32 -> String, +jn: String, xs: List<&2, U32>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
283 rep.put(~U32, ~(+x => val.enum(~name, x)), jn, xs, acc)
284
285
286def put.repeated.message(+name: String, vs: List<&1, Json.Val>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
287 match vs:
288 case Nil{}:
289 acc
290 case Con{h, t}:
291 put.always.v(name, Json.Arr{Con{h, t}}, acc)
292
293
294def put.map(+name: String, entries: List<&1, Bytes.Bytes & Json.Val>, acc: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, Bytes.Bytes & Json.Val>:
295 match entries:
296 case Nil{}:
297 acc
298 case Con{h, t}:
299 put.always.v(name, Json.Obj{Con{h, t}}, acc)
300
301
302def key.int32(+x: U32) -> String:
303 i32.show(x)
304
305def key.sint32(+x: U32) -> String:
306 i32.show(x)
307
308def key.sfixed32(+x: U32) -> String:
309 i32.show(x)
310
311def key.uint32(+x: U32) -> String:
312 U32.show(x)
313
314def key.fixed32(+x: U32) -> String:
315 U32.show(x)
316
317def key.int64(+w: Pb.Word64) -> String:
318 Pbr.word64.show_s(w)
319
320def key.sint64(+w: Pb.Word64) -> String:
321 Pbr.word64.show_s(w)
322
323def key.sfixed64(+w: Pb.Word64) -> String:
324 Pbr.word64.show_s(w)
325
326def key.uint64(+w: Pb.Word64) -> String:
327 Pbr.word64.show_u(w)
328
329def key.fixed64(+w: Pb.Word64) -> String:
330 Pbr.word64.show_u(w)
331
332def key.bool(+b: Bool) -> String:
333 Bool.pick(String, b, "true", "false")
334
335def key.string(+s: String) -> String:
336 s
337
338
339
340def encode(v: Json.Val) -> Bytes.Bytes:
341 Json.encode.bytes(v)
342
343def parse.fin(m: Maybe<&1, Json.Val>) -> Result<&2, &1, String, Json.Val>:
344 match m:
345 case None{}:
346 Fail{"invalid JSON"}
347 case Some{v}:
348 Done{v}
349
350def parse(b: Bytes.Bytes) -> Result<&2, &1, String, Json.Val>:
351 parse.fin(Json.parse.bytes(b))
352
353
354
355def fields.go(kvs: List<&1, Bytes.Bytes & Json.Val>) -> List<&1, String & Json.Val>:
356 match kvs:
357 case Nil{}:
358 Nil{}
359 case Con{(k, v), t}:
360 Con{(Enc.utf8.decode(k), v), fields.go(t)}
361
362
363
364def fields(v: Json.Val) -> Result<&2, &1, String, List<&1, String & Json.Val>>:
365 match v:
366 case Json.Obj{kvs}:
367 Done{fields.go(kvs)}
368 case Json.Null{}:
369 Fail{"expected a JSON object, got null"}
370 case Json.Flag{on}:
371 Fail{"expected a JSON object, got a boolean"}
372 case Json.Num{s}:
373 Fail{"expected a JSON object, got a number"}
374 case Json.Str{s}:
375 Fail{"expected a JSON object, got a string"}
376 case Json.Arr{xs}:
377 Fail{"expected a JSON object, got an array"}
378
379
380def read.map.entries(v: Json.Val) -> Result<&2, &1, String, List<&1, String & Json.Val>>:
381 match v:
382 case Json.Obj{kvs}:
383 Done{fields.go(kvs)}
384 case Json.Null{}:
385 Done{Nil{}}
386 case Json.Flag{on}:
387 Fail{"expected a JSON object for a map field"}
388 case Json.Num{s}:
389 Fail{"expected a JSON object for a map field"}
390 case Json.Str{s}:
391 Fail{"expected a JSON object for a map field"}
392 case Json.Arr{xs}:
393 Fail{"expected a JSON object for a map field"}
394
395
396type JKey is Data:
397 JKey{name: String, num: U32}
398
399
400
401def dispatch(+k: String, table: List<&2, JKey>) -> U32:
402 match table:
403 case Nil{}:
404 0
405 case Con{JKey{+name, +num}, t}:
406 Bool.pick(U32, String.eq(k, name), num, dispatch(k, t))
407
408def is_key(+k: String, +jn: String, +pn: String) -> Bool:
409 String.eq(k, jn) || String.eq(k, pn)
410
411def take.step(hit: Bool, k: String, v: Json.Val, r: Json.Val & List<&1, String & Json.Val>) -> Json.Val & List<&1, String & Json.Val>:
412 match hit:
413 case True{}:
414 (f, rest) = r
415 (v, rest)
416 case False{}:
417 (f, rest) = r
418 (f, Con{(k, v), rest})
419
420def take.go(+jn: String, +pn: String, kvs: List<&1, String & Json.Val>) -> Json.Val & List<&1, String & Json.Val>:
421 match kvs:
422 case Nil{}:
423 (Json.Null{}, Nil{})
424 case Con{(+k, v), t}:
425 take.step(is_key(k, jn, pn), k, v, take.go(jn, pn, t))
426
427
428
429
430def take(kvs: List<&1, String & Json.Val>, +json_name: String, +proto_name: String) -> Json.Val & List<&1, String & Json.Val>:
431 take.go(json_name, proto_name, kvs)
432
433
434
435def lift.m(-T: Data, m: Maybe<&2, T>, what: String) -> Result<&2, &1, String, T>:
436 match m:
437 case None{}:
438 Fail{what}
439 case Some{x}:
440 Done{x}
441
442def int32.fin(m: Maybe<&2, Pb.Word64>) -> Maybe<&2, U32>:
443 match m:
444 case None{}:
445 None{}
446 case Some{w}:
447 Pb.Word64{+h, +l} = w
448 Bool.pick(Maybe<&2, U32>, U32.is_eq(h, (0 - (l >> 31n) : U32)), Some{l}, None{})
449
450def uint32.fin(m: Maybe<&2, Pb.Word64>) -> Maybe<&2, U32>:
451 match m:
452 case None{}:
453 None{}
454 case Some{w}:
455 Pb.Word64{+h, +l} = w
456 Bool.pick(Maybe<&2, U32>, U32.is_zero(h), Some{l}, None{})
457
458
459def parse.int32(+s: String) -> Maybe<&2, U32>:
460 int32.fin(Pbr.word64.read_s(s))
461
462def parse.uint32(+s: String) -> Maybe<&2, U32>:
463 uint32.fin(Pbr.word64.read_u(s))
464
465def parse.int64(+s: String) -> Maybe<&2, Pb.Word64>:
466 Pbr.word64.read_s(s)
467
468def parse.uint64(+s: String) -> Maybe<&2, Pb.Word64>:
469 Pbr.word64.read_u(s)
470
471def parse.float(+s: String) -> Maybe<&2, F32>:
472 Bool.pick(Maybe<&2, F32>, String.eq(s, "NaN"), Some{Pbr.f32.of_bits(2143289344)},
473 Bool.pick(Maybe<&2, F32>, String.eq(s, "Infinity"), Some{Pbr.f32.of_bits(2139095040)},
474 Bool.pick(Maybe<&2, F32>, String.eq(s, "-Infinity"), Some{Pbr.f32.of_bits(4286578688)},
475 F32.read(s))))
476
477
478def read.scalar(~T: Data, ~parse: @+s: String -> Maybe<&2, T>, +dflt: T, +what: String, v: Json.Val) -> Result<&2, &1, String, T>:
479 match v:
480 case Json.Null{}:
481 Done{dflt}
482 case Json.Num{b}:
483 lift.m(T, parse(Bytes.to_string(b)), what)
484 case Json.Str{b}:
485 lift.m(T, parse(Enc.utf8.decode(b)), what)
486 case Json.Flag{on}:
487 Fail{what}
488 case Json.Arr{xs}:
489 Fail{what}
490 case Json.Obj{kvs}:
491 Fail{what}
492
493def read.int32(v: Json.Val) -> Result<&2, &1, String, U32>:
494 read.scalar(~U32, ~parse.int32, 0, "expected an int32", v)
495
496def read.sint32(v: Json.Val) -> Result<&2, &1, String, U32>:
497 read.scalar(~U32, ~parse.int32, 0, "expected an int32", v)
498
499def read.sfixed32(v: Json.Val) -> Result<&2, &1, String, U32>:
500 read.scalar(~U32, ~parse.int32, 0, "expected an int32", v)
501
502def read.uint32(v: Json.Val) -> Result<&2, &1, String, U32>:
503 read.scalar(~U32, ~parse.uint32, 0, "expected a uint32", v)
504
505def read.fixed32(v: Json.Val) -> Result<&2, &1, String, U32>:
506 read.scalar(~U32, ~parse.uint32, 0, "expected a uint32", v)
507
508def read.int64(v: Json.Val) -> Result<&2, &1, String, Pb.Word64>:
509 read.scalar(~Pb.Word64, ~parse.int64, Pb.Word64{0, 0}, "expected an int64", v)
510
511def read.sint64(v: Json.Val) -> Result<&2, &1, String, Pb.Word64>:
512 read.scalar(~Pb.Word64, ~parse.int64, Pb.Word64{0, 0}, "expected an int64", v)
513
514def read.sfixed64(v: Json.Val) -> Result<&2, &1, String, Pb.Word64>:
515 read.scalar(~Pb.Word64, ~parse.int64, Pb.Word64{0, 0}, "expected an int64", v)
516
517def read.uint64(v: Json.Val) -> Result<&2, &1, String, Pb.Word64>:
518 read.scalar(~Pb.Word64, ~parse.uint64, Pb.Word64{0, 0}, "expected a uint64", v)
519
520def read.fixed64(v: Json.Val) -> Result<&2, &1, String, Pb.Word64>:
521 read.scalar(~Pb.Word64, ~parse.uint64, Pb.Word64{0, 0}, "expected a uint64", v)
522
523def read.float(v: Json.Val) -> Result<&2, &1, String, F32>:
524 read.scalar(~F32, ~parse.float, 0.0, "expected a float", v)
525
526def read.double(v: Json.Val) -> Result<&2, &1, String, F32>:
527 read.scalar(~F32, ~parse.float, 0.0, "expected a double", v)
528
529def read.bool(v: Json.Val) -> Result<&2, &1, String, Bool>:
530 match v:
531 case Json.Null{}:
532 Done{False{}}
533 case Json.Flag{on}:
534 Done{on}
535 case Json.Num{s}:
536 Fail{"expected a boolean"}
537 case Json.Str{s}:
538 Fail{"expected a boolean"}
539 case Json.Arr{xs}:
540 Fail{"expected a boolean"}
541 case Json.Obj{kvs}:
542 Fail{"expected a boolean"}
543
544def read.string(v: Json.Val) -> Result<&2, &1, String, String>:
545 match v:
546 case Json.Null{}:
547 Done{""}
548 case Json.Str{b}:
549 Done{Enc.utf8.decode(b)}
550 case Json.Flag{on}:
551 Fail{"expected a string"}
552 case Json.Num{s}:
553 Fail{"expected a string"}
554 case Json.Arr{xs}:
555 Fail{"expected a string"}
556 case Json.Obj{kvs}:
557 Fail{"expected a string"}
558
559def bytes.fin(m: Maybe<&1, Bytes.Bytes>) -> Result<&2, &1, String, List<&2, U32>>:
560 match m:
561 case None{}:
562 Fail{"invalid base64"}
563 case Some{b}:
564 Done{Pbr.bytes.to_list(b)}
565
566
567def read.bytes(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
568 match v:
569 case Json.Null{}:
570 Done{Nil{}}
571 case Json.Str{b}:
572 bytes.fin(B64.decode(Enc.utf8.decode(b)))
573 case Json.Flag{on}:
574 Fail{"expected a base64 string"}
575 case Json.Num{s}:
576 Fail{"expected a base64 string"}
577 case Json.Arr{xs}:
578 Fail{"expected a base64 string"}
579 case Json.Obj{kvs}:
580 Fail{"expected a base64 string"}
581
582
583def read.enum(~from_name: @+s: String -> Maybe<&2, U32>, v: Json.Val) -> Result<&2, &1, String, U32>:
584 match v:
585 case Json.Null{}:
586 Done{0}
587 case Json.Str{b}:
588 lift.m(U32, from_name(Enc.utf8.decode(b)), "unknown enum value")
589 case Json.Num{b}:
590 lift.m(U32, parse.int32(Bytes.to_string(b)), "invalid enum number")
591 case Json.Flag{on}:
592 Fail{"expected an enum name or number"}
593 case Json.Arr{xs}:
594 Fail{"expected an enum name or number"}
595 case Json.Obj{kvs}:
596 Fail{"expected an enum name or number"}
597
598def opt.some(~T: Data, ~read: Json.Val -> Result<&2, &1, String, T>, v: Json.Val) -> Result<&2, &1, String, Maybe<&2, T>>:
599 do Result<&2, &1, String, Maybe<&2, T>>:
600 x : T <- read(v)
601 return Some{x}
602
603
604
605def read.opt(~T: Data, ~read: Json.Val -> Result<&2, &1, String, T>, v: Json.Val) -> Result<&2, &1, String, Maybe<&2, T>>:
606 match v:
607 case Json.Null{}:
608 Done{None{}}
609 case Json.Flag{on}:
610 opt.some(~T, ~read, Json.Flag{on})
611 case Json.Num{s}:
612 opt.some(~T, ~read, Json.Num{s})
613 case Json.Str{s}:
614 opt.some(~T, ~read, Json.Str{s})
615 case Json.Arr{xs}:
616 opt.some(~T, ~read, Json.Arr{xs})
617 case Json.Obj{kvs}:
618 opt.some(~T, ~read, Json.Obj{kvs})
619
620
621
622def rep.read(~T: Data, ~read: Json.Val -> Result<&2, &1, String, T>, xs: List<&1, Json.Val>) -> Result<&2, &1, String, List<&2, T>>:
623 match xs:
624 case Nil{}:
625 Done{Nil{}}
626 case Con{h, t}:
627 do Result<&2, &1, String, List<&2, T>>:
628 x : T <- read(h)
629 rest : List<&2, T> <- rep.read(~T, ~read, t)
630 return x <> rest
631
632
633def read.repeated(~T: Data, ~read: Json.Val -> Result<&2, &1, String, T>, v: Json.Val) -> Result<&2, &1, String, List<&2, T>>:
634 match v:
635 case Json.Null{}:
636 Done{Nil{}}
637 case Json.Arr{xs}:
638 rep.read(~T, ~read, xs)
639 case Json.Flag{on}:
640 Fail{"expected an array"}
641 case Json.Num{s}:
642 Fail{"expected an array"}
643 case Json.Str{s}:
644 Fail{"expected an array"}
645 case Json.Obj{kvs}:
646 Fail{"expected an array"}
647
648def read.repeated.double(v: Json.Val) -> Result<&2, &1, String, List<&2, F32>>:
649 read.repeated(~F32, ~read.double, v)
650
651def read.repeated.float(v: Json.Val) -> Result<&2, &1, String, List<&2, F32>>:
652 read.repeated(~F32, ~read.float, v)
653
654def read.repeated.int32(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
655 read.repeated(~U32, ~read.int32, v)
656
657def read.repeated.sint32(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
658 read.repeated(~U32, ~read.sint32, v)
659
660def read.repeated.sfixed32(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
661 read.repeated(~U32, ~read.sfixed32, v)
662
663def read.repeated.uint32(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
664 read.repeated(~U32, ~read.uint32, v)
665
666def read.repeated.fixed32(v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
667 read.repeated(~U32, ~read.fixed32, v)
668
669def read.repeated.int64(v: Json.Val) -> Result<&2, &1, String, List<&2, Pb.Word64>>:
670 read.repeated(~Pb.Word64, ~read.int64, v)
671
672def read.repeated.sint64(v: Json.Val) -> Result<&2, &1, String, List<&2, Pb.Word64>>:
673 read.repeated(~Pb.Word64, ~read.sint64, v)
674
675def read.repeated.sfixed64(v: Json.Val) -> Result<&2, &1, String, List<&2, Pb.Word64>>:
676 read.repeated(~Pb.Word64, ~read.sfixed64, v)
677
678def read.repeated.uint64(v: Json.Val) -> Result<&2, &1, String, List<&2, Pb.Word64>>:
679 read.repeated(~Pb.Word64, ~read.uint64, v)
680
681def read.repeated.fixed64(v: Json.Val) -> Result<&2, &1, String, List<&2, Pb.Word64>>:
682 read.repeated(~Pb.Word64, ~read.fixed64, v)
683
684def read.repeated.bool(v: Json.Val) -> Result<&2, &1, String, List<&2, Bool>>:
685 read.repeated(~Bool, ~read.bool, v)
686
687def read.repeated.string(v: Json.Val) -> Result<&2, &1, String, List<&2, String>>:
688 read.repeated(~String, ~read.string, v)
689
690def read.repeated.bytes(v: Json.Val) -> Result<&2, &1, String, List<&2, List<&2, U32>>>:
691 read.repeated(~List<&2, U32>, ~read.bytes, v)
692
693def read.repeated.enum(~from_name: @+s: String -> Maybe<&2, U32>, v: Json.Val) -> Result<&2, &1, String, List<&2, U32>>:
694 read.repeated(~U32, ~(v => read.enum(~from_name, v)), v)
695
696
697def read.key.int32(+s: String) -> Result<&2, &1, String, U32>:
698 lift.m(U32, parse.int32(s), "invalid int32 map key")
699
700def read.key.sint32(+s: String) -> Result<&2, &1, String, U32>:
701 lift.m(U32, parse.int32(s), "invalid int32 map key")
702
703def read.key.sfixed32(+s: String) -> Result<&2, &1, String, U32>:
704 lift.m(U32, parse.int32(s), "invalid int32 map key")
705
706def read.key.uint32(+s: String) -> Result<&2, &1, String, U32>:
707 lift.m(U32, parse.uint32(s), "invalid uint32 map key")
708
709def read.key.fixed32(+s: String) -> Result<&2, &1, String, U32>:
710 lift.m(U32, parse.uint32(s), "invalid uint32 map key")
711
712def read.key.int64(+s: String) -> Result<&2, &1, String, Pb.Word64>:
713 lift.m(Pb.Word64, parse.int64(s), "invalid int64 map key")
714
715def read.key.sint64(+s: String) -> Result<&2, &1, String, Pb.Word64>:
716 lift.m(Pb.Word64, parse.int64(s), "invalid int64 map key")
717
718def read.key.sfixed64(+s: String) -> Result<&2, &1, String, Pb.Word64>:
719 lift.m(Pb.Word64, parse.int64(s), "invalid int64 map key")
720
721def read.key.uint64(+s: String) -> Result<&2, &1, String, Pb.Word64>:
722 lift.m(Pb.Word64, parse.uint64(s), "invalid uint64 map key")
723
724def read.key.fixed64(+s: String) -> Result<&2, &1, String, Pb.Word64>:
725 lift.m(Pb.Word64, parse.uint64(s), "invalid uint64 map key")
726
727def read.key.bool(+s: String) -> Result<&2, &1, String, Bool>:
728 Bool.pick(Result<&2, &1, String, Bool>, String.eq(s, "true"), Done{True{}},
729 Bool.pick(Result<&2, &1, String, Bool>, String.eq(s, "false"), Done{False{}}, Fail{"invalid bool map key"}))
730
731def read.key.string(+s: String) -> Result<&2, &1, String, String>:
732 Done{s}
733
734def map.go(~K: Data, ~V: Data, ~E: Data, ~key: @+s: String -> Result<&2, &1, String, K>, ~value: Json.Val -> Result<&2, &1, String, V>, ~mk: @+k: K -> @+v: V -> E, es: List<&1, String & Json.Val>) -> Result<&2, &1, String, List<&2, E>>:
735 match es:
736 case Nil{}:
737 Done{Nil{}}
738 case Con{(k, v), t}:
739 do Result<&2, &1, String, List<&2, E>>:
740 kk : K <- key(k)
741 vv : V <- value(v)
742 rest : List<&2, E> <- map.go(~K, ~V, ~E, ~key, ~value, ~mk, t)
743 return mk(kk, vv) <> rest
744
745
746
747def read.map(~K: Data, ~V: Data, ~E: Data, ~key: @+s: String -> Result<&2, &1, String, K>, ~value: Json.Val -> Result<&2, &1, String, V>, ~mk: @+k: K -> @+v: V -> E, v: Json.Val) -> Result<&2, &1, String, List<&2, E>>:
748 do Result<&2, &1, String, List<&2, E>>:
749 es : List<&1, String & Json.Val> <- read.map.entries(v)
750 map.go(~K, ~V, ~E, ~key, ~value, ~mk, es)