tangled
alpha
login
or
join now
eldridge.cam
/
cartography
0
fork
atom
Trading card city builder game?
0
fork
atom
overview
issues
pulls
pipelines
get the builds back to normal
eldridge.cam
1 month ago
171f0391
dff3a45f
+49
-38
2 changed files
expand all
collapse all
unified
split
api
src
coder.gleam
request.gleam
+40
-31
api/src/coder.gleam
reviewed
···
15
15
import glepack/encode as glepack_encode
16
16
import glepack/error as glepack_error
17
17
18
18
+
pub type Encoder(encoding, error) =
19
19
+
fn(Codable) -> Result(encoding, error)
20
20
+
21
21
+
pub type Decoder(encoding, error) =
22
22
+
fn(encoding) -> Result(Codable, error)
23
23
+
18
24
pub opaque type Coder(encoding, encode_err, decode_err) {
19
25
Coder(
20
20
-
encode: fn(Codable) -> Result(encoding, encode_err),
21
21
-
decode: fn(encoding) -> Result(Codable, decode_err),
26
26
+
encode: Encoder(encoding, encode_err),
27
27
+
decode: Decoder(encoding, decode_err),
22
28
)
23
29
}
24
30
···
36
42
codec.decode(data)
37
43
}
38
44
39
39
-
pub opaque type EnumEncoderBuilder(t, ee, de) {
40
40
-
EnumEncoderBuilder(cases: List(VariantCoder(t, ee, de)), error: ee)
45
45
+
pub opaque type EnumEncoderBuilder(t, ee) {
46
46
+
EnumEncoderBuilder(cases: List(VariantCoder(t, EncoderError(ee))), error: ee)
41
47
}
42
48
43
43
-
pub opaque type VariantCoder(t, ee, de) {
44
44
-
VariantCoder(tag: String, coder: Coder(t, ee, de))
49
49
+
pub opaque type VariantCoder(t, ee) {
50
50
+
VariantCoder(tag: String, encoder: Encoder(t, ee))
45
51
}
46
52
47
53
pub type EncoderError(e) {
···
62
68
Bijection(from: fn(t) -> u, to: fn(u) -> t)
63
69
}
64
70
65
65
-
pub fn map(coder: Coder(t, ee, de), bimap: Bijection(t, u)) -> Coder(u, ee, de) {
66
66
-
Coder(
67
67
-
encode: fn(codable) {
68
68
-
use value <- result.map(coder.encode(codable))
69
69
-
bimap.from(value)
70
70
-
},
71
71
-
decode: fn(value) { coder.decode(bimap.to(value)) },
72
72
-
)
71
71
+
pub fn map_encoder(
72
72
+
encoder: Encoder(t, e),
73
73
+
transform: fn(t) -> u,
74
74
+
) -> Encoder(u, e) {
75
75
+
fn(codable) {
76
76
+
use value <- result.map(encoder(codable))
77
77
+
transform(value)
78
78
+
}
79
79
+
}
80
80
+
81
81
+
pub fn map_decoder(
82
82
+
decoder: Decoder(u, e),
83
83
+
transform: fn(t) -> u,
84
84
+
) -> Decoder(t, e) {
85
85
+
fn(value) { decoder(transform(value)) }
73
86
}
74
87
75
88
pub fn nil(codable: Codable) -> Result(Nil, EncoderError(e)) {
···
100
113
}
101
114
}
102
115
103
103
-
pub fn string(codable: Codable) -> Result(Float, EncoderError(e)) {
116
116
+
pub fn string(codable: Codable) -> Result(String, EncoderError(e)) {
104
117
case codable {
105
105
-
codable.Float(value) -> Ok(value)
118
118
+
codable.String(value) -> Ok(value)
106
119
_ -> Error(ExpectedString)
107
120
}
108
121
}
···
114
127
}
115
128
}
116
129
117
117
-
pub fn list(coder: Coder(t, ee, de)) {
130
130
+
pub fn list(coder: Coder(t, EncoderError(ee), de)) {
118
131
fn(codable: Codable) -> Result(List(t), EncoderError(ee)) {
119
132
case codable {
120
133
codable.List(value) ->
121
134
list.map(value, coder.encode)
122
135
|> result.all()
123
123
-
|> result.map_error(ListEncoderError)
124
136
_ -> Error(ExpectedList)
125
137
}
126
138
}
127
139
}
128
140
129
129
-
pub fn record(coder: Coder(t, ee, de)) {
141
141
+
pub fn record(coder: Coder(t, EncoderError(ee), de)) {
130
142
fn(codable: Codable) -> Result(Dict(String, t), EncoderError(ee)) {
131
143
case codable {
132
144
codable.Record(value) ->
···
138
150
})
139
151
|> result.all()
140
152
|> result.map(dict.from_list)
141
141
-
|> result.map_error(ListEncoderError)
142
153
_ -> Error(ExpectedList)
143
154
}
144
155
}
145
156
}
146
157
147
147
-
pub fn enum(error: ee) -> EnumEncoderBuilder(t, ee, de) {
158
158
+
pub fn enum(error: ee) -> EnumEncoderBuilder(t, ee) {
148
159
EnumEncoderBuilder(cases: [], error:)
149
160
}
150
161
151
162
pub fn variant(
152
152
-
enum_encoder: EnumEncoderBuilder(t, ee, de),
163
163
+
enum_encoder: EnumEncoderBuilder(t, ee),
153
164
tag: String,
154
154
-
coder: Coder(t, ee, de),
155
155
-
) -> EnumEncoderBuilder(t, ee, de) {
165
165
+
encoder: Encoder(t, EncoderError(ee)),
166
166
+
) -> EnumEncoderBuilder(t, ee) {
156
167
EnumEncoderBuilder(..enum_encoder, cases: [
157
157
-
VariantCoder(tag, coder),
168
168
+
VariantCoder(tag, encoder),
158
169
..enum_encoder.cases
159
170
])
160
171
}
···
162
173
fn encode_variant(
163
174
tag: String,
164
175
payload: Codable,
165
165
-
cases: List(VariantCoder(t, ee, de)),
176
176
+
cases: List(VariantCoder(t, EncoderError(ee))),
166
177
error: ee,
167
178
) -> Result(t, EncoderError(ee)) {
168
179
case cases {
169
180
[] -> Error(StructVariantError(error))
170
170
-
[VariantCoder(case_tag, coder), ..cases] -> {
181
181
+
[VariantCoder(case_tag, encoder), ..cases] -> {
171
182
case case_tag == tag {
172
172
-
True ->
173
173
-
coder.encode(payload)
174
174
-
|> result.map_error(fn(error) { StructEncoderError(tag, error) })
183
183
+
True -> encoder(payload)
175
184
False -> encode_variant(tag, payload, cases, error)
176
185
}
177
186
}
···
179
188
}
180
189
181
190
pub fn encode_with(
182
182
-
enum_encoder: EnumEncoderBuilder(t, ee, de),
191
191
+
enum_encoder: EnumEncoderBuilder(t, ee),
183
192
decoder: fn(t) -> Result(Codable, de),
184
193
) -> Coder(t, EncoderError(ee), de) {
185
194
Coder(
+9
-7
api/src/request.gleam
reviewed
···
10
10
InvalidTag
11
11
}
12
12
13
13
-
fn authenticate_coder() -> coder.Coder(Request, Error) {
14
14
-
coder.map(coder.string, coder.Bijection(from: Authenticate))
15
15
-
}
16
16
-
17
17
-
pub fn coder() -> coder.Coder(Request, Error) {
13
13
+
pub fn coder() -> coder.Coder(Request, coder.EncoderError(Error), e) {
18
14
coder.enum(InvalidTag)
19
19
-
|> coder.variant("Authenticate", authenticate_coder())
20
20
-
|> coder.variant("DebugAddCard", debug_add_card_coder())
15
15
+
|> coder.variant(
16
16
+
"Authenticate",
17
17
+
coder.map_encoder(coder.string, Authenticate),
18
18
+
)
19
19
+
|> coder.variant(
20
20
+
"DebugAddCard",
21
21
+
coder.map_encoder(coder.string, DebugAddCard),
22
22
+
)
21
23
|> coder.encode_with(fn(request) {
22
24
Ok(case request {
23
25
Authenticate(auth_token) ->