router.bend
bend-kit-router@0.1.1.1 · 52 lines · 0 definitions
1# Match an HTTP method and path to a handler. Source: https://github.com/paymog/bend-kit/tree/main/router
2import Base
3
4# route(wantMethod, gotMethod, "/users/:id", path) → Maybe params.
5
6def segs.one.if(h: String, acc: List<&2, String>, empty: Bool) -> List<&2, String>:
7 match empty:
8 case True{}:
9 acc
10 case False{}:
11 h <> acc
12
13def segs.one(+h: String, acc: List<&2, String>) -> List<&2, String>:
14 segs.one.if(h, acc, String.is_empty(h))
15
16def segs.keep(xs: List<&2, String>, acc: List<&2, String>) -> List<&2, String>:
17 match xs:
18 case Nil{}:
19 acc
20 case Con{h, t}:
21 segs.keep(t, segs.one(h, acc))
22
23def segs(s: String) -> List<&2, String>:
24 segs.keep(String.split(s, '/'), Nil{})
25
26def param(+seg: String) -> Bool:
27 String.starts_with(seg, ":")
28
29def zip(pat: List<&2, String>, got: List<&2, String>, +m: Map<&2, String>) -> Maybe<&2, Map<&2, String>>:
30 match pat:
31 case Nil{}:
32 match got:
33 case Nil{}:
34 Some{m}
35 case Con{h, t}:
36 None{}
37 case Con{+p, +pt}:
38 match got:
39 case Nil{}:
40 None{}
41 case Con{+g, +gt}:
42 Bool.pick(Maybe<&2, Map<&2, String>>, param(p), zip(pt, gt, Map.set(&2, String, m, String.drop(p, 1n), g)), Bool.pick(Maybe<&2, Map<&2, String>>, String.eq(p, g), zip(pt, gt, m), None{}))
43
44def route.ok(pattern: String, path: String, same: Bool) -> Maybe<&2, Map<&2, String>>:
45 match same:
46 case False{}:
47 None{}
48 case True{}:
49 zip(segs(pattern), segs(path), Map.new(&2, String))
50
51def route(want: String, method: String, pattern: String, path: String) -> Maybe<&2, Map<&2, String>>:
52 route.ok(pattern, path, String.eq(want, method))