router.bend

bend-kit-router@0.1.1.0 · 53 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
29@unsafe
30def zip(pat: List<&2, String>, got: List<&2, String>, +m: Map<&2, String>) -> Maybe<&2, Map<&2, String>>:
31  match pat:
32    case Nil{}:
33      match got:
34        case Nil{}:
35          Some{m}
36        case Con{h, t}:
37          None{}
38    case Con{+p, +pt}:
39      match got:
40        case Nil{}:
41          None{}
42        case Con{+g, +gt}:
43          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{}))
44
45def route.ok(pattern: String, path: String, same: Bool) -> Maybe<&2, Map<&2, String>>:
46  match same:
47    case False{}:
48      None{}
49    case True{}:
50      zip(segs(pattern), segs(path), Map.new(&2, String))
51
52def route(want: String, method: String, pattern: String, path: String) -> Maybe<&2, Map<&2, String>>:
53  route.ok(pattern, path, String.eq(want, method))