src/b64.bend
bendonnect-rpc@0.1.0.0 · 61 lines · 10 definitions
1
2
3
4import Base
5import bend-kit-bytes@0.3.2.0/bytes.bend as Bytes
6
7
8def strip_pad.pick(hit: Bool, h: Char, t: String, rest: Unit -> String) -> String:
9 match hit:
10 case True{}:
11 rest(Unit{})
12 case False{}:
13 SCon{h, t}
14
15def strip_pad.rev(s: String) -> String:
16 match s:
17 case SNil{}:
18 SNil{}
19 case SCon{Chr{+c}, +t}:
20 strip_pad.pick(U32.is_eq(c, 61), Chr{c}, t, u => strip_pad.rev(t))
21
22
23def swap2(s: String, +a1: U32, +b1: U32, +a2: U32, +b2: U32) -> String:
24 match s:
25 case SNil{}:
26 SNil{}
27 case SCon{Chr{+c}, t}:
28 SCon{Chr{Bool.pick(U32, U32.is_eq(c, a1), b1, Bool.pick(U32, U32.is_eq(c, a2), b2, c))}, swap2(t, a1, b1, a2, b2)}
29
30
31def encode_std(b: Bytes.Bytes) -> String:
32 Bytes.to_base64(b)
33
34
35def encode_std_raw(b: Bytes.Bytes) -> String:
36 String.reverse(strip_pad.rev(String.reverse(Bytes.to_base64(b))))
37
38
39def encode_url_raw(b: Bytes.Bytes) -> String:
40 swap2(encode_std_raw(b), 43, 45, 47, 95)
41
42def has_pad(s: String) -> Bool:
43 match s:
44 case SNil{}:
45 False{}
46 case SCon{Chr{+c}, t}:
47 Bool.or(U32.is_eq(c, 61), has_pad(t))
48
49def decode.padded(+s: String, +m: U32) -> Maybe<&1, Bytes.Bytes>:
50 Bool.pick(Maybe<&1, Bytes.Bytes>, U32.is_eq(m, 0), Bytes.from_base64(s),
51 Bool.pick(Maybe<&1, Bytes.Bytes>, U32.is_eq(m, 2), Bytes.from_base64(String.append(s, "==")),
52 Bool.pick(Maybe<&1, Bytes.Bytes>, U32.is_eq(m, 3), Bytes.from_base64(String.append(s, "=")),
53 None{})))
54
55def decode.norm(+s: String, +n: U32) -> Maybe<&1, Bytes.Bytes>:
56 Bool.pick(Maybe<&1, Bytes.Bytes>, has_pad(s), Bytes.from_base64(s), decode.padded(s, (n .&. 3 : U32)))
57
58
59
60def decode(+s: String) -> Maybe<&1, Bytes.Bytes>:
61 decode.norm(swap2(s, 45, 43, 95, 47), Bytes.count(s, 0))