-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathInternal.lean
More file actions
78 lines (62 loc) · 2.12 KB
/
Copy pathInternal.lean
File metadata and controls
78 lines (62 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import Init.System.IO
def String.init (s : String) := s.extract 0 (s.length - 1)
def Header := String × String
instance Header.ToString : ToString Header :=
⟨fun pair => pair.fst ++ ": " ++ pair.snd⟩
inductive Msg
| text : String → Msg
| binary : ByteArray → Msg
instance : ToString Msg :=
⟨λ m => match m with
| Msg.text str => str
| Msg.binary lst => toString lst⟩
structure Req :=
(path : String)
(method : String)
(version : String)
(headers : List Header)
inductive Result
| error {} : String → Result
| warning {} : String → Result
| reply {} : Msg → Result
| ok {} : Result
def Handler := Req → Msg → Result
structure Proto :=
(ev : Type) -- Output type for protocol handler and input type for event handler
(nothing : Result)
(proto : Msg → ev)
structure Cx (m : Proto) :=
(req : Req) (module : m.ev → Result)
def Context.run (m : Proto) (cx : Cx m)
(handlers : List (Cx m → Cx m)) (msg : Msg) :=
(handlers.foldl (λ x (f : Cx m → Cx m) => f x) cx).module (m.proto msg)
def uselessRouter (m : Proto) : m.ev → Result :=
λ _ => m.nothing
def mkHandler (m : Proto) (handlers : List (Cx m → Cx m)) : Handler :=
λ req msg => Context.run m ⟨req, uselessRouter m⟩ handlers msg
structure WS :=
(question : Msg)
(headers : Array (String × String))
def Header.dropBack : Header → Option Header
| (name, value) =>
if name.back = ':' then some (name.init, value)
else none
def Header.isHeader : String → Bool
| "get " => true
| "post " => true
| "option " => true
| _ => false
def WS.toReq (socket : WS) : Req :=
let headersList := socket.headers.toList;
let headers := List.filterMap Header.dropBack headersList;
{ path := Option.getD
(headersList.lookup "get " <|>
headersList.lookup "post " <|>
headersList.lookup "option ") "",
method := Option.getD
(String.trimRight <$> Prod.fst <$>
headersList.find? (Header.isHeader ∘ Prod.fst)) "",
version := Option.getD
(Prod.snd <$> headersList.find?
(String.isPrefixOf "http" ∘ Prod.fst)) "",
headers := headers }