Current section

Files

Jump to
gladvent src gladvent@internal@runners.erl
Raw

src/gladvent@internal@runners.erl

-module(gladvent@internal@runners).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([pkg_interface/0, runner_retrieval_error_to_snag/1, get_day/3]).
-export_type([pkg_interface_err/0, runner_retrieval_err/0]).
-type pkg_interface_err() :: {failed_to_gleam_build, binary()} |
{failed_to_read_gleam_toml, simplifile:file_error()} |
{failed_to_decode_gleam_toml, tom:parse_error()} |
{failed_to_get_package_name, tom:get_error()} |
{failed_to_generate_package_interface, binary()} |
{failed_to_read_package_interface, simplifile:file_error()} |
{failed_to_clear_build_cache, simplifile:file_error()} |
{failed_to_decode_package_interface, gleam@json:decode_error()}.
-type runner_retrieval_err() :: {module_not_found, binary()} |
{parse_function_invalid, binary()} |
{function_not_found, binary(), binary()} |
{incorrect_input_parameters,
binary(),
binary(),
list(gleam@package_interface:type())}.
-spec snagify_error(
fun(() -> {ok, MWK} | {error, MWL}),
fun((MWL) -> snag:snag())
) -> {ok, MWK} | {error, snag:snag()}.
snagify_error(F, M) ->
_pipe = F(),
gleam@result:map_error(_pipe, M).
-spec package_interface_error_to_snag(pkg_interface_err()) -> snag:snag().
package_interface_error_to_snag(E) ->
case E of
{failed_to_gleam_build, S} ->
_pipe = snag:new(S),
snag:layer(_pipe, <<"failed to build gleam project"/utf8>>);
{failed_to_decode_gleam_toml, E@1} ->
_pipe@1 = snag:new(gleam@string:inspect(E@1)),
snag:layer(_pipe@1, <<"failed to decode gleam.toml"/utf8>>);
{failed_to_get_package_name, E@2} ->
_pipe@2 = snag:new(gleam@string:inspect(E@2)),
snag:layer(_pipe@2, <<"failed to get package name"/utf8>>);
{failed_to_read_gleam_toml, E@3} ->
_pipe@3 = snag:new(gleam@string:inspect(E@3)),
snag:layer(_pipe@3, <<"failed to read gleam.toml"/utf8>>);
{failed_to_clear_build_cache, E@4} ->
_pipe@4 = snag:new(gleam@string:inspect(E@4)),
snag:layer(_pipe@4, <<"failed to clear build cache"/utf8>>);
{failed_to_generate_package_interface, S@1} ->
_pipe@5 = snag:new(S@1),
snag:layer(
_pipe@5,
<<"failed to generate "/utf8, "build/.gladvent/pkg.json"/utf8>>
);
{failed_to_read_package_interface, E@5} ->
_pipe@6 = snag:new(gleam@string:inspect(E@5)),
snag:layer(
_pipe@6,
<<"failed to read "/utf8, "build/.gladvent/pkg.json"/utf8>>
);
{failed_to_decode_package_interface, E@6} ->
_pipe@7 = snag:new(gleam@string:inspect(E@6)),
snag:layer(
_pipe@7,
<<"failed to decode package interface json"/utf8>>
)
end.
-spec pkg_interface() -> {ok, gleam@package_interface:package()} |
{error, snag:snag()}.
pkg_interface() ->
snagify_error(
fun() ->
Spinner = begin
_pipe = spinner:new(
<<"generating "/utf8, "build/.gladvent/pkg.json"/utf8>>
),
spinner:start(_pipe)
end,
gladvent@internal@util:defer(
fun() -> spinner:stop(Spinner) end,
fun() ->
Root = gladvent@internal@cmd:root(),
gleam@result:'try'(
begin
_pipe@1 = simplifile:read(
filepath:join(Root, <<"gleam.toml"/utf8>>)
),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {failed_to_read_gleam_toml, Field@0} end
)
end,
fun(Gleam_toml) ->
gleam@result:'try'(
begin
_pipe@2 = tom:parse(Gleam_toml),
gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {failed_to_decode_gleam_toml, Field@0} end
)
end,
fun(Toml) ->
gleam@result:'try'(
begin
_pipe@3 = tom:get_string(
Toml,
[<<"name"/utf8>>]
),
gleam@result:map_error(
_pipe@3,
fun(Field@0) -> {failed_to_get_package_name, Field@0} end
)
end,
fun(Name) ->
gleam@result:'try'(
begin
_pipe@6 = (gleam@list:try_map(
[<<"build/prod/erlang"/utf8>>,
<<"build/dev/erlang"/utf8>>],
fun(Cache) ->
_pipe@4 = filepath:join(
Root,
Cache
),
_pipe@5 = filepath:join(
_pipe@4,
Name
),
simplifile:delete(
_pipe@5
)
end
)),
gleam@result:try_recover(
_pipe@6,
fun(E) -> case E of
enoent ->
{ok, []};
_ ->
{error,
{failed_to_clear_build_cache,
E}}
end end
)
end,
fun(_) ->
gleam@result:'try'(
begin
_pipe@7 = shellout:command(
<<"gleam"/utf8>>,
[<<"build"/utf8>>],
Root,
[]
),
gleam@result:map_error(
_pipe@7,
fun(E@1) ->
{failed_to_generate_package_interface,
erlang:element(
2,
E@1
)}
end
)
end,
fun(_) ->
gleam@result:'try'(
begin
_pipe@8 = shellout:command(
<<"gleam"/utf8>>,
[<<"export"/utf8>>,
<<"package-interface"/utf8>>,
<<"--out"/utf8>>,
<<"build/.gladvent/pkg.json"/utf8>>],
Root,
[]
),
gleam@result:map_error(
_pipe@8,
fun(E@2) ->
{failed_to_generate_package_interface,
erlang:element(
2,
E@2
)}
end
)
end,
fun(_) ->
spinner:set_text(
Spinner,
<<"reading "/utf8,
"build/.gladvent/pkg.json"/utf8>>
),
gleam@result:'try'(
begin
_pipe@9 = simplifile:read(
filepath:join(
gladvent@internal@cmd:root(
),
<<"build/.gladvent/pkg.json"/utf8>>
)
),
gleam@result:map_error(
_pipe@9,
fun(Field@0) -> {failed_to_read_package_interface, Field@0} end
)
end,
fun(
Pkg_interface_contents
) ->
spinner:set_text(
Spinner,
<<"decoding package interface JSON"/utf8>>
),
gleam@result:'try'(
begin
_pipe@10 = gleam@json:decode(
Pkg_interface_contents,
fun gleam@package_interface:decoder/1
),
gleam@result:map_error(
_pipe@10,
fun(Field@0) -> {failed_to_decode_package_interface, Field@0} end
)
end,
fun(
Pkg_interface_details
) ->
{ok,
Pkg_interface_details}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end,
fun package_interface_error_to_snag/1
).
-spec to_erlang_module_name(binary()) -> binary().
to_erlang_module_name(Name) ->
gleam@string:replace(Name, <<"/"/utf8>>, <<"@"/utf8>>).
-spec parse_function(binary()) -> fun((binary()) -> gleam@dynamic:dynamic_()).
parse_function(Module) ->
gladvent_ffi:parse_function(
erlang:binary_to_atom(to_erlang_module_name(Module))
).
-spec type_to_string(gleam@package_interface:type()) -> binary().
type_to_string(T) ->
case T of
{tuple, Elements} ->
<<<<"#("/utf8, (type_list_to_string(Elements))/binary>>/binary,
")"/utf8>>;
{fn, Parameters, Return} ->
<<<<<<"fn("/utf8, (type_list_to_string(Parameters))/binary>>/binary,
") -> "/utf8>>/binary,
(type_to_string(Return))/binary>>;
{variable, Id} ->
gleam@int:to_string(Id);
{named, Name, _, Module, Parameters@1} ->
case Parameters@1 of
[] ->
<<<<Module/binary, "."/utf8>>/binary, Name/binary>>;
_ ->
<<<<<<<<<<Module/binary, "."/utf8>>/binary, Name/binary>>/binary,
"("/utf8>>/binary,
(type_list_to_string(Parameters@1))/binary>>/binary,
")"/utf8>>
end
end.
-spec type_list_to_string(list(gleam@package_interface:type())) -> binary().
type_list_to_string(Lt) ->
_pipe = Lt,
_pipe@1 = gleam@list:map(_pipe, fun type_to_string/1),
gleam@string:join(_pipe@1, <<", "/utf8>>).
-spec runner_retrieval_error_to_snag(runner_retrieval_err()) -> snag:snag().
runner_retrieval_error_to_snag(E) ->
case E of
{module_not_found, M} ->
snag:new(<<<<"module "/utf8, M/binary>>/binary, " not found"/utf8>>);
{parse_function_invalid, F} ->
_pipe = snag:new(F),
snag:layer(_pipe, <<"parse function invalid"/utf8>>);
{function_not_found, M@1, F@1} ->
snag:new(
<<<<<<"module "/utf8, M@1/binary>>/binary,
" does not export function "/utf8>>/binary,
F@1/binary>>
);
{incorrect_input_parameters, F@2, E@1, G} ->
_pipe@1 = (<<<<<<<<<<"function '"/utf8, F@2/binary>>/binary,
"' has parameter(s) "/utf8>>/binary,
(type_list_to_string(G))/binary>>/binary,
", but should only have one parameter and it must be of type "/utf8>>/binary,
E@1/binary>>),
snag:new(_pipe@1)
end.
-spec retrieve_runner(
binary(),
gleam@package_interface:module_(),
binary(),
gleam@package_interface:type()
) -> {ok, fun((gleam@dynamic:dynamic_()) -> gleam@dynamic:dynamic_())} |
{error, runner_retrieval_err()}.
retrieve_runner(Module_name, Module, Function_name, Runner_param_type) ->
gleam@result:'try'(
begin
_pipe = erlang:element(6, Module),
_pipe@1 = gleam@dict:get(_pipe, Function_name),
gleam@result:replace_error(
_pipe@1,
{function_not_found, Module_name, Function_name}
)
end,
fun(Pt_1) -> gleam@bool:guard(case erlang:element(5, Pt_1) of
[Param] ->
erlang:element(3, Param) /= Runner_param_type;
_ ->
true
end, {error,
{incorrect_input_parameters,
Function_name,
type_to_string(Runner_param_type),
gleam@list:map(
erlang:element(5, Pt_1),
fun(P) -> erlang:element(3, P) end
)}}, fun() ->
{ok,
gladvent_ffi:function_arity_one(
erlang:binary_to_atom(
to_erlang_module_name(Module_name)
),
erlang:binary_to_atom(Function_name)
)}
end) end
).
-spec get_day(gleam@package_interface:package(), integer(), integer()) -> {ok,
{fun((gleam@dynamic:dynamic_()) -> gleam@dynamic:dynamic_()),
fun((gleam@dynamic:dynamic_()) -> gleam@dynamic:dynamic_()),
gleam@option:option(fun((binary()) -> gleam@dynamic:dynamic_()))}} |
{error, snag:snag()}.
get_day(Package, Year, Day) ->
snagify_error(
fun() ->
Module_name = <<<<<<"aoc_"/utf8,
(gleam@int:to_string(Year))/binary>>/binary,
"/day_"/utf8>>/binary,
(gleam@int:to_string(Day))/binary>>,
gleam@result:'try'(
begin
_pipe = gleam@dict:get(
erlang:element(5, Package),
Module_name
),
gleam@result:replace_error(
_pipe,
{module_not_found, Module_name}
)
end,
fun(Module) ->
Parse = gleam@dict:get(
erlang:element(6, Module),
<<"parse"/utf8>>
),
gleam@result:'try'(case Parse of
{error, nil} ->
{ok,
{named,
<<"String"/utf8>>,
<<""/utf8>>,
<<"gleam"/utf8>>,
[]}};
{ok, {function, _, _, _, [Param], Return}} when erlang:element(
3,
Param
) =:= {named,
<<"String"/utf8>>,
<<""/utf8>>,
<<"gleam"/utf8>>,
[]} ->
{ok, Return};
_ ->
{error,
{parse_function_invalid,
<<"parse function must have 1 input parameter of type String"/utf8>>}}
end, fun(Runner_param_type) ->
Retrieve_runner = fun(_capture) ->
retrieve_runner(
Module_name,
Module,
_capture,
Runner_param_type
)
end,
gleam@result:'try'(
Retrieve_runner(<<"pt_1"/utf8>>),
fun(Pt_1) ->
gleam@result:'try'(
Retrieve_runner(<<"pt_2"/utf8>>),
fun(Pt_2) ->
{ok,
{Pt_1,
Pt_2,
begin
_pipe@1 = Parse,
_pipe@2 = gleam@result:replace(
_pipe@1,
parse_function(
Module_name
)
),
gleam@option:from_result(
_pipe@2
)
end}}
end
)
end
)
end)
end
)
end,
fun runner_retrieval_error_to_snag/1
).