-module(glint). -compile(no_auto_import). -export([new/0, add_command/4, execute/2, run/2]). -export_type([command_input/0, command/0]). -type command_input() :: {command_input, list(binary()), gleam@map:map_(binary(), glint@flag:flag_value())}. -opaque command() :: {command, gleam@option:option(fun((command_input()) -> nil)), gleam@map:map_(binary(), command()), gleam@map:map_(binary(), glint@flag:flag_value())}. -spec new() -> command(). new() -> {command, none, gleam@map:new(), gleam@map:new()}. -spec add_command( command(), list(binary()), fun((command_input()) -> nil), list(glint@flag:flag()) ) -> command(). 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) -> case Node of none -> add_command( {command, none, gleam@map:new(), gleam@map:new()}, Xs, F, Flags ); {some, Node@1} -> add_command(Node@1, Xs, F, Flags) end end, erlang:setelement( 3, Root, gleam@map:update(erlang:element(3, Root), X, Update_subcommand) ) end. -spec execute_root(command(), list(binary())) -> {ok, nil} | {error, snag:snag()}. execute_root(Cmd, Args) -> case erlang:element(2, Cmd) of {some, F} -> {ok, F({command_input, Args, erlang:element(4, Cmd)})}; none -> {error, begin _pipe = snag:new(<<"command not found"/utf8>>), snag:layer(_pipe, <<"failed to run command"/utf8>>) end} end. -spec execute(command(), list(binary())) -> {ok, nil} | {error, snag:snag()}. execute(Cmd, Args) -> case Args of [] -> execute_root(Cmd, []); [Arg | Rest] -> case gleam@string:starts_with(Arg, <<"-"/utf8>>) of true -> case begin _pipe = glint@flag:update_flags( erlang:element(4, Cmd), gleam@string:drop_left(Arg, 1) ), snag:context(_pipe, <<"failed to run command"/utf8>>) end of {error, _try} -> {error, _try}; {ok, New_flags} -> execute(erlang:setelement(4, Cmd, New_flags), Rest) end; false -> case gleam@map:get(erlang:element(3, Cmd), Arg) of {ok, Cmd@1} -> execute(Cmd@1, Rest); {error, _@1} -> execute_root(Cmd, Args) end end end. -spec run(command(), list(binary())) -> nil. run(Cmd, Args) -> case execute(Cmd, Args) of {ok, nil} -> nil; {error, Err} -> _pipe = Err, _pipe@1 = snag:pretty_print(_pipe), gleam@io:println(_pipe@1) end.