-module(cmd@run). -compile(no_auto_import). -export([build_runners_from_days_dir/0, register_command/2, run/2]). -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 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>> ), _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) ), _pipe@4 = gleam@result:map(_pipe@3, fun gleam@string:trim/1), gleam@result:map(_pipe@4, Day_runner) 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\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 => 142}) 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 => 150}) 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).