Skip to content

Commit 1eb8d41

Browse files
authored
typed expectations make it easier to validate (#15)
1 parent e8db5b2 commit 1eb8d41

File tree

1 file changed

+68
-34
lines changed

1 file changed

+68
-34
lines changed

src/gladvent/internal/cmd/run.gleam

Lines changed: 68 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ fn do(
8383
)
8484

8585
let input_path = input.get_file_path(year, day, input_kind)
86-
8786
use input <- result.try(
8887
input_path
8988
|> simplifile.read()
@@ -209,21 +208,47 @@ fn solve_err_to_string(solve_err: SolveErr) -> String {
209208

210209
fn solve_res_to_string(
211210
res: SolveResult,
212-
expectation: option.Option(String),
211+
expectation: option.Option(Expectation),
213212
) -> String {
214-
case res {
215-
Ok(res) -> {
216-
let res = string.inspect(res)
217-
case res, expectation {
218-
_, option.None -> res
219-
_, option.Some(expectation) if res == expectation ->
220-
"✅ met expected value: " <> res
221-
_, option.Some(expectation) ->
222-
"❌ unmet expectation: got " <> res <> ", expected " <> expectation
223-
}
224-
}
225-
Error(err) -> solve_err_to_string(err)
226-
}
213+
result.unwrap_both({
214+
use res <- result.map(res |> result.map_error(solve_err_to_string))
215+
option.lazy_unwrap(
216+
{
217+
use expect <- option.map(expectation)
218+
case expect {
219+
ExpectInt(expect) -> {
220+
case dynamic.int(res) {
221+
Ok(i) if expect == i ->
222+
"✅ met expected value: " <> int.to_string(i)
223+
Ok(i) ->
224+
"❌ unmet expectation: expected "
225+
<> int.to_string(expect)
226+
<> ", got "
227+
<> int.to_string(i)
228+
Error(_) ->
229+
"❌ expected "
230+
<> int.to_string(expect)
231+
<> ", got non-integer value of "
232+
<> string.inspect(res)
233+
}
234+
}
235+
ExpectString(expect) -> {
236+
case dynamic.string(res) {
237+
Ok(s) if expect == s -> "✅ met expected value: " <> s
238+
Ok(s) ->
239+
"❌ unmet expectation: expected " <> expect <> ", got " <> s
240+
Error(_) ->
241+
"❌ expected "
242+
<> expect
243+
<> ", got non-string value of "
244+
<> string.inspect(res)
245+
}
246+
}
247+
}
248+
},
249+
or: fn() { string.inspect(res) },
250+
)
251+
})
227252
}
228253

229254
import gleam/pair
@@ -233,30 +258,23 @@ fn collect_async(
233258
x: #(Day, AsyncResult),
234259
expectations: Option(dict.Dict(String, tom.Toml)),
235260
) -> String {
236-
let expect_pt_1 =
237-
expectations
238-
|> option.then(fn(ex) {
239-
toml_get_int_or_string(ex, [int.to_string(x.0), "pt_1"])
240-
|> option.from_result
241-
})
242-
let expect_pt_2 =
243-
expectations
244-
|> option.then(fn(ex) {
245-
toml_get_int_or_string(ex, [int.to_string(x.0), "pt_2"])
246-
|> option.from_result
247-
})
261+
let expect = fn(key) {
262+
use ex <- option.then(expectations)
263+
toml_decode_expectation(ex, [int.to_string(x.0), key])
264+
|> option.from_result
265+
}
248266

249267
x
250268
|> pair.map_second(result.map_error(_, Other))
251269
|> pair.map_second(result.flatten)
252-
|> collect(year, _, expect_pt_1, expect_pt_2)
270+
|> collect(year, _, expect("pt_1"), expect("pt_2"))
253271
}
254272

255273
fn collect(
256274
year: Int,
257275
x: #(Day, RunResult),
258-
expect_pt_1: Option(String),
259-
expect_pt_2: Option(String),
276+
expect_pt_1: Option(Expectation),
277+
expect_pt_2: Option(Expectation),
260278
) -> String {
261279
let day = int.to_string(x.0)
262280
case x.1 {
@@ -429,8 +447,24 @@ fn read_gleam_toml() {
429447
})
430448
}
431449

432-
fn toml_get_int_or_string(toml: dict.Dict(String, tom.Toml), path: List(String)) {
433-
tom.get_int(toml, path)
434-
|> result.map(int.to_string)
435-
|> result.try_recover(fn(_) { tom.get_string(toml, path) })
450+
type Expectation {
451+
ExpectInt(Int)
452+
ExpectString(String)
453+
}
454+
455+
fn toml_decode_expectation(
456+
toml: dict.Dict(String, tom.Toml),
457+
path: List(String),
458+
) -> gleam.Result(Expectation, tom.GetError) {
459+
use data <- result.try(tom.get(toml, path))
460+
case data {
461+
tom.String(s) -> Ok(ExpectString(s))
462+
tom.Int(i) -> Ok(ExpectInt(i))
463+
_ ->
464+
Error(tom.WrongType(
465+
key: path,
466+
expected: "Int or String",
467+
got: "something else",
468+
))
469+
}
436470
}

0 commit comments

Comments
 (0)