def encode.go

bend-kit-cbor@0.3.0.0 · cbor.bend:316

import bend-kit-cbor@0.3.0.0/cbor.bend as Cbor
import Base
import bend-kit-bytes@0.3.3.0/bytes.bend as Bytes

316# fuel bounds the steps; size(v) gives enough, so the 0n arm is never reached.
317def encode.go(fuel: Nat, items: List<&1, Item>, o: W) -> Maybe<&1, W>:
318  match fuel:
319    case 0n:
320      None{}
321    case 1n+fuel:
322      match items:
323        case Nil{}:
324          Some{o}
325        case Con{IGuard{ok}, rest}:
326          match ok:
327            case True{}:
328              encode.go(fuel, rest, o)
329            case False{}:
330              None{}
331        case Con{IText{value}, rest}:
332          (b, ok) = value
333          Bytes.Bytes{+len, buf} = b
334          encode.go(fuel, Con{IGuard{ok}, rest}, raw.bytes(Bytes.Bytes{len, buf}, head.u32(3, len, o)))
335        case Con{IArrLen{value}, rest}:
336          (xs, n) = value
337          encode.go(fuel, Con{IArr{xs}, rest}, head.u32(4, U32.from_nat(n), o))
338        case Con{IMapLen{value}, rest}:
339          (kvs, n) = value
340          encode.go(fuel, Con{IMap{kvs}, rest}, head.u32(5, U32.from_nat(n), o))
341        case Con{IArr{xs}, rest}:
342          match xs:
343            case Nil{}:
344              encode.go(fuel, rest, o)
345            case Con{h, t}:
346              encode.go(fuel, Con{IVal{h}, Con{IArr{t}, rest}}, o)
347        case Con{IMap{kvs}, rest}:
348          match kvs:
349            case Nil{}:
350              encode.go(fuel, rest, o)
351            case Con{(k, v), t}:
352              encode.go(fuel, Con{IVal{k}, Con{IVal{v}, Con{IMap{t}, rest}}}, o)
353        case Con{IVal{value}, rest}:
354          match value:
355            case UInt{value}:
356              encode.go(fuel, rest, uint.bytes(0, value, o))
357            case NInt{value}:
358              encode.go(fuel, rest, uint.bytes(1, value, o))
359            case BStr{value}:
360              Bytes.Bytes{+len, buf} = value
361              encode.go(fuel, rest, raw.bytes.go(U32.to_nat(len), Bytes.peek(buf, 0), 0, head.u32(2, len, o)))
362            case TStr{value}:
363              encode.go(fuel, Con{IText{text.check(value)}, rest}, o)
364            case Arr{items}:
365              encode.go(fuel, Con{IArrLen{vals.length(items)}, rest}, o)
366            case Obj{items}:
367              encode.go(fuel, Con{IMapLen{pairs.length(items)}, rest}, o)
368            case Tag{number, value}:
369              encode.go(fuel, Con{IVal{value}, rest}, uint.bytes(6, number, o))
370            case Sim{value}:
371              match value:
372                case SFalse{}:
373                  encode.go(fuel, rest, byte(o, 244))
374                case STrue{}:
375                  encode.go(fuel, rest, byte(o, 245))
376                case SNull{}:
377                  encode.go(fuel, rest, byte(o, 246))
378                case SUndefined{}:
379                  encode.go(fuel, rest, byte(o, 247))
380                case Other{+value}:
381                  encode.go(fuel, Con{IGuard{simple.ok(value)}, rest}, head.u32(7, value, o))
382            case Flt{value}:
383              match value:
384                case Half{+bits}:
385                  encode.go(fuel, Con{IGuard{U32.is_lt(bits, 65536)}, rest}, byte(byte(byte(o, 249), (bits >> 8n : U32)), bits))
386                case Single{+bits}:
387                  encode.go(fuel, rest, raw.u32(byte(o, 250), bits))
388                case Double{+bits}:
389                  W64{+hi, +lo} = bits
390                  encode.go(fuel, rest, raw.u32(raw.u32(byte(o, 251), hi), lo))

Uses (28)

Used by (1)