From f600f1f5fad7e3f1f4edfc933c0b69041808b9cd Mon Sep 17 00:00:00 2001 From: Robert Attard Date: Mon, 13 Nov 2023 17:01:06 -0500 Subject: [PATCH] switch to task.await_forever and task.await --- .github/workflows/main.yml | 2 - src/gladvent/internal/cmd.gleam | 23 ++++---- src/gladvent/internal/cmd/new.gleam | 22 +++++--- src/gladvent/internal/cmd/run.gleam | 86 +++++++++++++++-------------- 4 files changed, 71 insertions(+), 62 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6fb0f4a..47e5cc1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,11 +7,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - gleam: ["0.28.1"] erlang: ["24.2"] steps: - uses: actions/checkout@v2 - uses: ./.github/actions/test with: - gleam-version: ${{ matrix.gleam }} erlang-version: ${{ matrix.erlang }} diff --git a/src/gladvent/internal/cmd.gleam b/src/gladvent/internal/cmd.gleam index 415cbac..4d248b2 100644 --- a/src/gladvent/internal/cmd.gleam +++ b/src/gladvent/internal/cmd.gleam @@ -61,29 +61,26 @@ fn try_await_many( Endless -> { use tup <- list.map(tasks) use t <- pair.map_second(tup) - task.try_await_forever(t) - |> result.map_error(await_err_to_string) + Ok(task.await_forever(t)) } Ending(timeout) -> { let end = now_ms() + timeout use tup <- list.map(tasks) use t <- pair.map_second(tup) - end - now_ms() - |> int.clamp(min: 0, max: timeout) - |> task.try_await(t, _) - |> result.map_error(await_err_to_string) + let res = + end - now_ms() + |> int.clamp(min: 0, max: timeout) + |> task.try_await(t, _) + use err <- result.map_error(res) + case err { + task.Timeout -> "task timed out" + task.Exit(s) -> "task exited for some reason: " <> string.inspect(s) + } } } } -fn await_err_to_string(err: task.AwaitError) -> String { - case err { - task.Timeout -> "task timed out" - task.Exit(s) -> "task exited for some reason: " <> string.inspect(s) - } -} - @external(erlang, "erlang", "localtime") fn date() -> #(#(Int, Int, Int), #(Int, Int, Int)) diff --git a/src/gladvent/internal/cmd/new.gleam b/src/gladvent/internal/cmd/new.gleam index b917254..d2f43a4 100644 --- a/src/gladvent/internal/cmd/new.gleam +++ b/src/gladvent/internal/cmd/new.gleam @@ -148,16 +148,24 @@ pub fn pt_2(input: String) { } " -fn collect(year: Int, x: #(Day, Result(String, String))) -> String { - let day = int.to_string(x.0) - let year = int.to_string(year) +import gleam - "initialized " <> year <> " day " <> day <> "\n" <> { - case x.1 { - Ok(ok) -> ok +fn collect_async(year: Int, x: #(Day, Result(String, String))) -> String { + fn(res) { + case res { + Ok(res) -> res Error(err) -> err } } + |> pair.map_second(x, _) + |> collect(year, _) +} + +fn collect(year: Int, x: #(Day, String)) -> String { + let day = int.to_string(x.0) + let year = int.to_string(year) + + "initialized " <> year <> " day " <> day <> "\n" <> x.1 } pub fn new_command() { @@ -169,7 +177,7 @@ pub fn new_command() { days, cmd.Endless, fn(day) { do(Context(year, day)) }, - collect(year, _), + collect_async(year, _), ) } |> glint.description("Create .gleam and input files") diff --git a/src/gladvent/internal/cmd/run.gleam b/src/gladvent/internal/cmd/run.gleam index 65796ac..784348e 100644 --- a/src/gladvent/internal/cmd/run.gleam +++ b/src/gladvent/internal/cmd/run.gleam @@ -16,20 +16,28 @@ import gleam import gladvent/internal/runners.{type RunnerMap} import gleam/dynamic.{type Dynamic} import gleam/option.{type Option, None} -import gleam/pair -type SolveErr { - Undef - RunFailed(String) -} +type AsyncResult = + gleam.Result(RunResult, String) -type Err { +type RunErr { FailedToReadInput(String) Unregistered(Day) Other(String) } -fn err_to_snag(err: Err) -> Snag { +type RunResult = + gleam.Result(#(SolveResult, SolveResult), RunErr) + +type SolveErr { + Undef + RunFailed(String) +} + +type SolveResult = + gleam.Result(Dynamic, SolveErr) + +fn run_err_to_snag(err: RunErr) -> Snag { case err { Unregistered(day) -> "day" <> " " <> int.to_string(day) <> " " <> "unregistered" @@ -39,9 +47,6 @@ fn err_to_snag(err: Err) -> Snag { |> snag.new } -type RunResult = - gleam.Result(Dynamic, SolveErr) - type Direction { // Leading // Trailing @@ -55,12 +60,7 @@ fn string_trim(s: String, dir: Direction, sub: String) -> String { @external(erlang, "string", "trim") fn do_trim(a: String, b: Direction, c: Charlist) -> String -fn do( - year: Int, - day: Day, - runners: RunnerMap, - allow_crash: Bool, -) -> gleam.Result(#(RunResult, RunResult), Err) { +fn do(year: Int, day: Day, runners: RunnerMap, allow_crash: Bool) -> RunResult { use #(pt_1, pt_2) <- result.then( runners |> map.get(day) @@ -83,11 +83,11 @@ fn do( let pt_1 = fn() { pt_1(input) } |> erlang.rescue - |> result.map_error(run_err_to_string) + |> result.map_error(crash_to_string) let pt_2 = fn() { pt_2(input) } |> erlang.rescue - |> result.map_error(run_err_to_string) + |> result.map_error(crash_to_string) Ok(#(pt_1, pt_2)) } } @@ -149,9 +149,9 @@ fn gleam_err_to_string(g: GleamErr) -> String { ) } -fn run_err_to_string(err: erlang.Crash) -> SolveErr { - let dyn = crash_to_dyn(err) - decode_gleam_err()(dyn) +fn crash_to_string(err: erlang.Crash) -> SolveErr { + crash_to_dyn(err) + |> decode_gleam_err() |> result.map(gleam_err_to_string) |> result.lazy_unwrap(fn() { "run failed for some reason: " <> string.inspect(err) @@ -159,35 +159,41 @@ fn run_err_to_string(err: erlang.Crash) -> SolveErr { |> RunFailed } -fn run_res_to_string(res: RunResult) -> String { +fn solve_err_to_string(solve_err: SolveErr) -> String { + case solve_err { + Undef -> "function undefined" + RunFailed(s) -> s + } +} + +fn solve_res_to_string(res: SolveResult) -> String { case res { Ok(res) -> string.inspect(res) - Error(err) -> - case err { - Undef -> "function undefined" - RunFailed(s) -> s - } + Error(err) -> solve_err_to_string(err) } } -fn collect( - year: Int, - x: #(Day, gleam.Result(gleam.Result(#(RunResult, RunResult), Err), String)), -) -> String { +import gleam/pair + +fn collect_async(year: Int, x: #(Day, AsyncResult)) -> String { + x + |> pair.map_second(result.map_error(_, Other)) + |> pair.map_second(result.flatten) + |> collect(year, _) +} + +fn collect(year: Int, x: #(Day, RunResult)) -> String { let day = int.to_string(x.0) - let x = - x - |> pair.map_second(result.map_error(_, Other)) - |> pair.map_second(result.flatten) + case x.1 { Ok(#(res_1, res_2)) -> - "Ran " <> int.to_string(year) <> " day " <> day <> ":\n" <> " Part 1: " <> run_res_to_string( + "Ran " <> int.to_string(year) <> " day " <> day <> ":\n" <> " Part 1: " <> solve_res_to_string( res_1, - ) <> "\n" <> " Part 2: " <> run_res_to_string(res_2) + ) <> "\n" <> " Part 2: " <> solve_res_to_string(res_2) Error(err) -> err - |> err_to_snag + |> run_err_to_snag |> snag.layer("Failed to run " <> int.to_string(year) <> " day " <> day) |> snag.pretty_print() } @@ -228,7 +234,7 @@ pub fn run_command() -> glint.Command(Result(List(String))) { |> cmd.exec( timing(input.flags), do(year, _, runners, allow_crash), - collect(year, _), + collect_async(year, _), ) |> Ok } @@ -249,7 +255,7 @@ pub fn run_all_command() -> glint.Command(Result(List(String))) { |> cmd.exec( timing(input.flags), do(year, _, runners, allow_crash), - collect(year, _), + collect_async(year, _), ) |> Ok }