-module(glint). -compile(no_auto_import). -export([new/0, add_command/4, execute/2, run/2]). -export_type([command_input/0, command/1]). -type command_input() :: {command_input, list(binary()), gleam@map:map_(binary(), glint@flag:flag_value())}. -opaque command(EKD) :: {command, gleam@option:option(fun((command_input()) -> EKD)), gleam@map:map_(binary(), command(EKD)), gleam@map:map_(binary(), glint@flag:flag_value())}. -spec new() -> command(any()). new() -> {command, none, gleam@map:new(), gleam@map:new()}. -spec sanitize_path(list(binary())) -> list(binary()). sanitize_path(Path) -> _pipe = Path, _pipe@1 = gleam@list:map(_pipe, fun gleam@string:trim/1), gleam@list:filter( _pipe@1, gleam@function:compose( fun gleam@string:is_empty/1, fun gleam@bool:negate/1 ) ). -spec add_command( command(EKS), list(binary()), fun((command_input()) -> EKS), list(glint@flag:flag()) ) -> command(EKS). add_command(Root, Path, F, Flags) -> _pipe = Path, _pipe@1 = sanitize_path(_pipe), do_add_command(Root, _pipe@1, F, Flags). -spec do_add_command( command(EKY), list(binary()), fun((command_input()) -> EKY), list(glint@flag:flag()) ) -> command(EKY). do_add_command(Root, Path, F, Flags) -> case Path of [] -> erlang:setelement( 4, erlang:setelement(2, Root, {some, F}), glint@flag:build_map(Flags) ); [X | Xs] -> Update_subcommand = fun(Node) -> _pipe = Node, _pipe@1 = gleam@option:lazy_unwrap(_pipe, fun new/0), do_add_command(_pipe@1, Xs, F, Flags) end, erlang:setelement( 3, Root, gleam@map:update(erlang:element(3, Root), X, Update_subcommand) ) end. -spec execute_root(command(ELE), list(binary()), list(binary())) -> {ok, ELE} | {error, snag:snag()}. execute_root(Cmd, Args, Flags) -> case erlang:element(2, Cmd) of {some, F} -> case begin _pipe = Flags, _pipe@1 = gleam@list:try_fold( _pipe, erlang:element(4, Cmd), fun glint@flag:update_flags/2 ), snag:context(_pipe@1, <<"failed to run command"/utf8>>) end of {error, _try} -> {error, _try}; {ok, New_flags} -> _pipe@2 = Args, _pipe@3 = {command_input, _pipe@2, New_flags}, _pipe@4 = F(_pipe@3), {ok, _pipe@4} end; none -> _pipe@5 = snag:new(<<"command not found"/utf8>>), _pipe@6 = snag:layer(_pipe@5, <<"failed to run command"/utf8>>), {error, _pipe@6} end. -spec execute(command(ELJ), list(binary())) -> {ok, ELJ} | {error, snag:snag()}. execute(Cmd, Args) -> {Flags, Args@1} = gleam@list:partition( Args, fun(_capture) -> gleam@string:starts_with(_capture, <<"--"/utf8>>) end ), do_execute(Cmd, Args@1, Flags). -spec do_execute(command(ELN), list(binary()), list(binary())) -> {ok, ELN} | {error, snag:snag()}. do_execute(Cmd, Args, Flags) -> case Args of [] -> execute_root(Cmd, [], Flags); [Arg | Rest] -> case gleam@map:get(erlang:element(3, Cmd), Arg) of {ok, Cmd@1} -> do_execute(Cmd@1, Rest, Flags); _@1 -> execute_root(Cmd, Args, Flags) end end. -spec run(command(any()), list(binary())) -> nil. run(Cmd, Args) -> case execute(Cmd, Args) of {error, Err} -> _pipe = Err, _pipe@1 = snag:pretty_print(_pipe), gleam@io:println(_pipe@1); _@1 -> nil end.