-
Notifications
You must be signed in to change notification settings - Fork 2
/
Types.lean
133 lines (101 loc) · 2.58 KB
/
Types.lean
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import Std
namespace Http
namespace URI
def Hostname := String
deriving instance ToString for Hostname
def Scheme := String
deriving BEq
def Scheme.mk (s: String) := s
deriving instance ToString for Scheme
def Path := List String
instance : ToString Path where
toString p := p.foldl (λ acc s => acc ++ s) "/"
structure UserInfo where
username : String
password : Option String
instance : ToString UserInfo where
toString ui := ""
def Fragment := List (String × String)
instance : ToString Fragment where
toString (q : Fragment) := "#" ++ ("&".intercalate <| q.map (λ (k, v) => s!"{k}={v}"))
def Query := List (String × String)
instance : ToString Query where
toString (q : Query) := "?" ++ ("&".intercalate <| q.map (λ (k, v) => s!"{k}={v}"))
end URI
open URI
structure URI where
userInfo : Option UserInfo
host: Hostname
port: Option UInt16
scheme: Scheme
path: Path
query: Option Query
fragment: Option Fragment
def CRLF : String := "\r\n"
/--
A Case insensitive String with case insensitive BEq and Hashable instances.
-/
def CaseInsString := String
deriving ToString
instance caseInsensitiveStringBEq : BEq CaseInsString where
beq s1 s2 := s1.capitalize == s2.capitalize
instance caseInsensitiveStringHashable : Hashable CaseInsString where
hash s := s.capitalize.hash
inductive Method
| GET
| HEAD
| POST
| PUT
| DELETE
| CONNECT
| OPTIONS
| TRACE
| PATCH
def Method.toString: Method → String
| GET => "GET"
| HEAD => "HEAD"
| POST => "POST"
| PUT => "PUT"
| DELETE => "DELETE"
| CONNECT => "CONNECT"
| OPTIONS => "OPTIONS"
| TRACE => "TRACE"
| PATCH => "PATCH"
instance : ToString Method where
toString := Method.toString
inductive Protocol
| http (version : String)
| https (version : String)
| other (name : String) (version : String)
def Protocol.toString : Protocol → String
| http v => s!"HTTP/{v}"
| https v => s!"HTTPS/{v}"
| other name v => s!"{name.capitalize}/{v}"
open Protocol in
def URI.Scheme.asProtocol (s : Scheme) : Protocol :=
match ToString.toString s with
| "http" => http "1.1"
| "https" => https "1.2"
| s => other s ""
instance : ToString Protocol where
toString := Protocol.toString
/-
Meta information for Requests and Responses.
-/
def Headers := Std.HashMap CaseInsString String
structure Request where
url : URI
protocol : Protocol
method : Method
headers : Headers
body : Option String
/-
A HTTP response from a request.
-/
structure Response where
message : String
protocol : Protocol
statusCode : Nat
headers : Headers
body : Option String
end Http