Current section

Files

Jump to
gladvent src cmd@run.erl
Raw

src/cmd@run.erl

-module(cmd@run).
-compile(no_auto_import).
-export([do_run/2, build_runners_from_days_dir/0, register_command/2, run/2]).
-export_type([run_error/0]).
-type run_error() :: undef | run_failed.
-spec to_module(binary()) -> gleam@erlang@atom:atom_().
to_module(File) ->
_pipe = File,
_pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>),
_pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>),
gleam@erlang@atom:create_from_string(_pipe@3).
-spec do_run(fun((binary()) -> {integer(), integer()}), binary()) -> {ok,
{integer(),
integer()}} |
{error, run_error()}.
do_run(A, B) ->
gladvent_ffi:do_run(A, B).
-spec get_runner(binary()) -> {ok,
{integer(),
fun((binary()) -> {integer(), integer()})}} |
{error, snag:snag()}.
get_runner(Filename) ->
case begin
_pipe = gleam@string:replace(Filename, <<"day_"/utf8>>, <<""/utf8>>),
_pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>),
_pipe@2 = parse:day(_pipe@1),
snag:context(
_pipe@2,
gleam@string:append(<<"cannot create runner for "/utf8>>, Filename)
)
end of
{error, _try} -> {error, _try};
{ok, Day} ->
Run = begin
_pipe@3 = Filename,
_pipe@4 = gleam@string:append(<<"days/"/utf8>>, _pipe@3),
_pipe@5 = to_module(_pipe@4),
gladvent_ffi:get_run(_pipe@5)
end,
{ok, {Day, Run}}
end.
-spec get_runners() -> {ok,
list({integer(),
fun((binary()) -> {integer(), integer()})})} |
{error, snag:snag()}.
get_runners() ->
_pipe = gladvent_ffi:find_files(
<<"day_*.gleam"/utf8>>,
<<"src/days/"/utf8>>
),
gleam@list:try_map(_pipe, fun get_runner/1).
-spec build_runners_from_days_dir() -> {ok,
gleam@map:map_(integer(), fun((binary()) -> {integer(),
integer()}))} |
{error, snag:snag()}.
build_runners_from_days_dir() ->
case get_runners() of
{error, _try} -> {error, _try};
{ok, Runners} ->
{ok, gleam@map:from_list(Runners)}
end.
-spec do(
integer(),
gleam@map:map_(integer(), fun((binary()) -> {integer(), integer()}))
) -> {ok, {integer(), integer()}} | {error, snag:snag()}.
do(Day, Runners) ->
case begin
_pipe = gleam@map:get(Runners, Day),
gleam@result:replace_error(_pipe, unrecognized_day_err(Day))
end of
{error, _try} -> {error, _try};
{ok, Day_runner} ->
Input_path = gleam@string:join(
[<<"input/day_"/utf8>>,
gleam@int:to_string(Day),
<<".txt"/utf8>>],
<<""/utf8>>
),
case begin
_pipe@1 = Input_path,
_pipe@2 = gleam@erlang@file:read(_pipe@1),
_pipe@3 = gleam@result:replace_error(
_pipe@2,
failed_to_read_input_err(Input_path)
),
gleam@result:map(_pipe@3, fun gleam@string:trim/1)
end of
{error, _try@1} -> {error, _try@1};
{ok, Input} ->
case gladvent_ffi:do_run(Day_runner, Input) of
{error, undef} ->
snag:error(<<"run function undefined"/utf8>>);
{error, _@1} ->
snag:error(<<"some error occurred"/utf8>>);
{ok, Res} ->
{ok, Res}
end
end
end.
-spec unrecognized_day_err(integer()) -> snag:snag().
unrecognized_day_err(Day) ->
_pipe = Day,
_pipe@1 = gleam@int:to_string(_pipe),
_pipe@2 = gleam@string:append(<<"unrecognized day: "/utf8>>, _pipe@1),
snag:new(_pipe@2).
-spec failed_to_read_input_err(binary()) -> snag:snag().
failed_to_read_input_err(Input_path) ->
_pipe = Input_path,
_pipe@1 = snag:new(_pipe),
snag:layer(_pipe@1, <<"failed to read input file"/utf8>>).
-spec collect({{ok, {integer(), integer()}} | {error, snag:snag()}, integer()}) -> binary().
collect(X) ->
Day = gleam@int:to_string(erlang:element(2, X)),
case erlang:element(1, X) of
{ok, {Res_1, Res_2}} ->
_pipe = [<<"Ran day "/utf8>>,
Day,
<<":"/utf8>>,
<<"\n Part 1: "/utf8>>,
gleam@int:to_string(Res_1),
<<"\n Part 2: "/utf8>>,
gleam@int:to_string(Res_2)],
gleam@string:concat(_pipe);
{error, Err} ->
_pipe@1 = gleam@string:append(<<"Error on day "/utf8>>, Day),
_pipe@2 = snag:layer(Err, _pipe@1),
snag:pretty_print(_pipe@2)
end.
-spec exec(
list(integer()),
cmd:timing(),
gleam@map:map_(integer(), fun((binary()) -> {integer(), integer()}))
) -> binary().
exec(Days, Timing, Runners) ->
_pipe = Days,
_pipe@1 = cmd:exec(
_pipe,
Timing,
fun(_capture) -> do(_capture, Runners) end,
fun collect/1
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>).
-spec register_command(
glint:command(),
gleam@map:map_(integer(), fun((binary()) -> {integer(), integer()}))
) -> glint:command().
register_command(Glint, Runners) ->
glint:add_command(
Glint,
[<<"run"/utf8>>],
fun(_capture) -> run(_capture, Runners) end,
[glint@flag:int(<<"timeout"/utf8>>, 0),
glint@flag:bool(<<"all"/utf8>>, false)]
).
-spec run(
glint:command_input(),
gleam@map:map_(integer(), fun((binary()) -> {integer(), integer()}))
) -> nil.
run(Input, Runners) ->
{ok, {i, Timeout@1}} = case gleam@map:get(
erlang:element(3, Input),
<<"timeout"/utf8>>
) of
{ok, {i, Timeout}} -> {ok, {i, Timeout}};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"cmd/run"/utf8>>,
function => <<"run"/utf8>>,
line => 159})
end,
Timing = case Timeout@1 of
0 ->
{ok, endless};
_@1 when Timeout@1 < 0 ->
{error, invalid_timeout_err(Timeout@1)};
_@2 ->
{ok, {ending, Timeout@1}}
end,
{ok, {b, All@1}} = case gleam@map:get(
erlang:element(3, Input),
<<"all"/utf8>>
) of
{ok, {b, All}} -> {ok, {b, All}};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"cmd/run"/utf8>>,
function => <<"run"/utf8>>,
line => 167})
end,
Days = case All@1 of
true ->
_pipe = Runners,
_pipe@1 = gleam@map:keys(_pipe),
_pipe@2 = gleam@list:sort(_pipe@1, fun gleam@int:compare/2),
{ok, _pipe@2};
false ->
parse:days(erlang:element(2, Input))
end,
_pipe@3 = case {Days, Timing} of
{{ok, Days@1}, {ok, Timing@1}} ->
exec(Days@1, Timing@1, Runners);
{_@3, {error, Err}} ->
snag:pretty_print(Err);
{{error, Err@1}, _@4} ->
failed_to_parse_err(Err@1, erlang:element(2, Input))
end,
gleam@io:println(_pipe@3).
-spec invalid_timeout_err(integer()) -> snag:snag().
invalid_timeout_err(Timeout) ->
_pipe = [<<"invalid timeout value "/utf8>>,
<<"'"/utf8>>,
gleam@int:to_string(Timeout),
<<"'"/utf8>>],
_pipe@1 = gleam@string:concat(_pipe),
_pipe@2 = snag:new(_pipe@1),
_pipe@3 = snag:layer(
_pipe@2,
<<"timeout must be greater than or equal to 1 ms"/utf8>>
),
snag:layer(_pipe@3, <<"failed to run advent of code"/utf8>>).
-spec failed_to_parse_err(snag:snag(), list(binary())) -> binary().
failed_to_parse_err(Err, Args) ->
_pipe = Err,
_pipe@1 = snag:layer(
_pipe,
gleam@string:join(
[<<"failed to parse arguments"/utf8>> | Args],
<<" "/utf8>>
)
),
_pipe@2 = snag:layer(_pipe@1, <<"failed to run advent of code"/utf8>>),
snag:pretty_print(_pipe@2).