-module(cmd). -compile(no_auto_import). -export([exec/4]). -export_type([timing/0]). -type timing() :: endless | {ending, integer()}. -spec exec( list(integer()), timing(), fun((integer()) -> {ok, FXY} | {error, snag:snag()}), fun(({{ok, FXY} | {error, snag:snag()}, integer()}) -> binary()) ) -> list(binary()). exec(Days, Timing, Do, Collect) -> _pipe = Days, _pipe@1 = task_map(_pipe, Do), _pipe@2 = try_await_many(_pipe@1, Timing), _pipe@3 = gleam@iterator:from_list(_pipe@2), _pipe@4 = gleam@iterator:map(_pipe@3, fun gleam@result:flatten/1), _pipe@5 = gleam@iterator:zip(_pipe@4, gleam@iterator:from_list(Days)), _pipe@6 = gleam@iterator:map(_pipe@5, Collect), gleam@iterator:to_list(_pipe@6). -spec now_ms() -> integer(). now_ms() -> gleam@erlang:system_time(millisecond). -spec task_map(list(FYD), fun((FYD) -> FYF)) -> list(gleam@otp@task:task(FYF)). task_map(L, F) -> gleam@list:map(L, fun(X) -> gleam@otp@task:async(fun() -> F(X) end) end). -spec try_await_many(list(gleam@otp@task:task(FYI)), timing()) -> list({ok, FYI} | {error, snag:snag()}). try_await_many(Tasks, Timing) -> Await = case Timing of endless -> fun(T) -> _pipe = T, _pipe@1 = gleam@otp@task:try_await(_pipe, 600000), gleam@result:map_error(_pipe@1, fun snag_task_error/1) end; {ending, Timeout} -> End = now_ms() + Timeout, fun(T@1) -> _pipe@2 = End - now_ms(), _pipe@3 = gleam@int:clamp(_pipe@2, 0, Timeout), _pipe@4 = gleam@otp@task:try_await(T@1, _pipe@3), gleam@result:map_error(_pipe@4, fun snag_task_error/1) end end, gleam@list:map(Tasks, Await). -spec snag_task_error(gleam@otp@task:await_error()) -> snag:snag(). snag_task_error(Err) -> _pipe = case Err of timeout -> <<"task timed out"/utf8>>; {exit, _@1} -> <<"task exited for some reason"/utf8>> end, snag:new(_pipe).