1 # Match an HTTP method and path to a handler. Source: https://github.com/paymog/bend-kit/tree/main/router 2 import Base 3 4 # route(wantMethod, gotMethod, "/users/:id", path) → Maybe params. 5 6 def 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 13 def segs.one(+h: String, acc: List<&2, String>) -> List<&2, String>: 14 segs.one.if(h, acc, String.is_empty(h)) 15 16 def 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 23 def segs(s: String) -> List<&2, String>: 24 segs.keep(String.split(s, '/'), Nil{}) 25 26 def param(+seg: String) -> Bool: 27 String.starts_with(seg, ":") 28 29 def 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 44 def 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 51 def route(want: String, method: String, pattern: String, path: String) -> Maybe<&2, Map<&2, String>>: 52 route.ok(pattern, path, String.eq(want, method))