-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUri.hs
138 lines (94 loc) · 4.04 KB
/
Uri.hs
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
134
135
136
137
138
{-# Language EmptyDataDecls #-}
module Uri where
import FFI
import Prelude
-- | Creation and conversion
-- Choose to make Uri an opaque data type. If the accessors on the
-- jsUri objects were properties and not functions we could have
-- defined Uri as a record instead.
data Uri
-- To make Google Closure play nice we use [] instead of . for accessing properties.
currentUri :: Fay String
currentUri = ffi "window['location']['href']"
-- This assumes that Uri is defined globally, which it is by default.
newUri :: String -> Uri
newUri = ffi "new window['Uri'](%1)"
toString :: Uri -> String
toString = ffi "%1['toString']()"
-- If we ever want to pass a Uri back to JS we need to make sure we keep persistance internally.
clone :: Uri -> Uri
clone = ffi "%1['clone']()"
-- | Getters
-- All getters (except query! But lets be consistent) may return null if the value isn't set so we use
-- Language.FFI.Nullable here which converts null -> Null and String -> Nullable String.
-- Nullable is distinguished from Maybe to not break haskell compatibility.
-- If we want to decode null into Nullable (Nullable a) there is no way of
-- knowing if Null or Nullable Null is correct. This problem does not exist when
-- working with Maybe values in client server communication.
protocol :: Uri -> Nullable String
protocol = ffi "%1['protocol']()"
userInfo :: Uri -> Nullable String
userInfo = ffi "%1['userInfo']()"
host :: Uri -> Nullable String
host = ffi "%1['host']()"
port :: Uri -> Nullable String
port = ffi "%1['port']()"
path :: Uri -> Nullable String
path = ffi "%1['path']()"
query :: Uri -> Nullable String
query = ffi "%1['query']()"
anchor :: Uri -> Nullable String
anchor = ffi "%1['anchor']()"
-- | Other getters
queryParamValue :: String -> Uri -> String
queryParamValue = ffi "%2['getQueryParamValue'](%1)"
queryParamValues :: String -> Uri -> [String]
queryParamValues = ffi "%2['getQueryParamValues'](%1)"
-- | Setters
-- We could use Nullable here to combine the with* and remove* functions
-- but usage would be more verbose that way.
-- JsUri has clone() conveniently defined so we use it to get
-- persistence, otherwise our types would be `-> Fay Uri` which is of
-- course worse.
withProtocol :: String -> Uri -> Uri
withProtocol = ffi "%2['clone']()['setProtocol'](%1)"
withUserInfo :: String -> Uri -> Uri
withUserInfo = ffi "%2['clone']()['setUserInfo'](%1)"
withHost :: String -> Uri -> Uri
withHost = ffi "%2['clone']()['setHost'](%1)"
withPort :: String -> Uri -> Uri
withPort = ffi "%2['clone']()['setPort'](%1)"
withPath :: String -> Uri -> Uri
withPath = ffi "%2['clone']()['setPath'](%1)"
withQuery :: String -> Uri -> Uri
withQuery = ffi "%2['clone']()['setQuery'](%1)"
withAnchor :: String -> Uri -> Uri
withAnchor = ffi "%2['clone']()['setAnchor'](%1)"
-- | Removals
removeProtocol :: Uri -> Uri
removeProtocol = ffi "%1['clone']()['setProtocol'](null)"
removeUserInfo :: Uri -> Uri
removeUserInfo = ffi "%1['clone']()['setUserInfo'](null)"
removeHost :: Uri -> Uri
removeHost = ffi "%1['clone']()['setHost'](null)"
removePort :: Uri -> Uri
removePort = ffi "%1['clone']()['setPort'](null)"
removePath :: Uri -> Uri
removePath = ffi "%1['clone']()['setPath'](null)"
removeQuery :: Uri -> Uri
removeQuery = ffi "%1['clone']()['setQuery'](null)"
removeAnchor :: Uri -> Uri
removeAnchor = ffi "%1['clone']()['setAnchor'](null)"
-- | Other setters
addQueryParam :: String -> String -> Uri -> Uri
addQueryParam = ffi "%3['clone']()['addQueryParam'](%1,%2)"
replaceQueryParam :: String -> String -> Uri -> Uri
replaceQueryParam = ffi "%3['clone']()['replaceQueryParam'](%1,%2)"
-- The order of the arguments differ from the jsUri api, it is now
-- key -> oldValue -> newValue -> Uri -> Uri
replaceQueryParamValue :: String -> String -> String -> Uri -> Uri
replaceQueryParamValue = ffi "%4['clone']()['replaceQueryParam'](%1, %3, %2)"
deleteQueryParam :: String -> Uri -> Uri
deleteQueryParam = ffi "%2['clone']()['deleteQueryParam'](%1)"
deleteQueryParamValue :: String -> String -> Uri -> Uri
deleteQueryParamValue = ffi "%3['clone']()['deleteQueryParam'](%1,%2)"