-module(cigogne@internal@cli_lib). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/cigogne/internal/cli_lib.gleam"). -export([command/1, with_description/2, add_action/2, create_action/3, with_help/2, options/1, then_action/2, map_action/2, flag/6, decode_string/1, map/2, then/3, required/2, args_to_dict/1, decode_bool/1, decode_int/1, run/2]). -export_type([command/1, action/1, action_decoder/1, flag/0, flag_decoder/1, parse_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type command(IHA) :: {command, binary(), binary(), list(action(IHA))}. -type action(IHB) :: {action, list(binary()), binary(), action_decoder(IHB)}. -type action_decoder(IHC) :: {action_decoder, IHC, list(flag()), fun((gleam@dict:dict(binary(), list(binary()))) -> {IHC, list(parse_error())})}. -type flag() :: {flag, binary(), list(binary()), binary(), binary()}. -type flag_decoder(IHD) :: {flag_decoder, IHD, fun((gleam@option:option(list(binary()))) -> {ok, IHD} | {error, binary()})}. -type parse_error() :: {parse_error, binary(), binary()}. -file("src/cigogne/internal/cli_lib.gleam", 44). ?DOC(false). -spec command(binary()) -> command(any()). command(Name) -> {command, Name, <<""/utf8>>, []}. -file("src/cigogne/internal/cli_lib.gleam", 48). ?DOC(false). -spec with_description(command(IHG), binary()) -> command(IHG). with_description(Command, Description) -> _record = Command, {command, erlang:element(2, _record), Description, erlang:element(4, _record)}. -file("src/cigogne/internal/cli_lib.gleam", 52). ?DOC(false). -spec add_action(command(IHJ), action(IHJ)) -> command(IHJ). add_action(Command, Action) -> _record = Command, {command, erlang:element(2, _record), erlang:element(3, _record), [Action | erlang:element(4, Command)]}. -file("src/cigogne/internal/cli_lib.gleam", 56). ?DOC(false). -spec create_action(list(binary()), binary(), action_decoder(IHO)) -> action(IHO). create_action(Action_path, Help, Decoder) -> {action, Action_path, Help, Decoder}. -file("src/cigogne/internal/cli_lib.gleam", 64). ?DOC(false). -spec with_help(action(IHR), binary()) -> action(IHR). with_help(Action, Help) -> _record = Action, {action, erlang:element(2, _record), Help, erlang:element(4, _record)}. -file("src/cigogne/internal/cli_lib.gleam", 68). ?DOC(false). -spec options(IHU) -> action_decoder(IHU). options(Data) -> {action_decoder, Data, [], fun(_) -> {Data, []} end}. -file("src/cigogne/internal/cli_lib.gleam", 72). ?DOC(false). -spec then_action(action_decoder(IHW), fun((IHW) -> action_decoder(IHY))) -> action_decoder(IHY). then_action(Decoder, Then_fn) -> Decoder2 = Then_fn(erlang:element(2, Decoder)), {action_decoder, erlang:element(2, Decoder2), lists:append(erlang:element(3, Decoder), erlang:element(3, Decoder2)), fun(V) -> {Res1, Err1} = (erlang:element(4, Decoder))(V), {Res2, Err2} = (erlang:element(4, Then_fn(Res1)))(V), {Res2, lists:append(Err1, Err2)} end}. -file("src/cigogne/internal/cli_lib.gleam", 88). ?DOC(false). -spec map_action(action_decoder(IIB), fun((IIB) -> IID)) -> action_decoder(IID). map_action(Decoder, Map_fn) -> {action_decoder, Map_fn(erlang:element(2, Decoder)), erlang:element(3, Decoder), fun(V) -> {Res, Err} = (erlang:element(4, Decoder))(V), {Map_fn(Res), Err} end}. -file("src/cigogne/internal/cli_lib.gleam", 133). ?DOC(false). -spec get_argument(list(binary()), gleam@dict:dict(binary(), list(binary()))) -> gleam@option:option({binary(), list(binary())}). get_argument(Names, Args) -> case Names of [] -> none; [Name | Rest] -> case gleam_stdlib:map_get(Args, Name) of {error, _} -> get_argument(Rest, Args); {ok, Arg_value} -> {some, {Name, Arg_value}} end end. -file("src/cigogne/internal/cli_lib.gleam", 147). ?DOC(false). -spec result_to_tuple({ok, IIR} | {error, list(IIS)}, IIR) -> {IIR, list(IIS)}. result_to_tuple(Value, Default_value) -> case Value of {ok, V} -> {V, []}; {error, Errs} -> {Default_value, Errs} end. -file("src/cigogne/internal/cli_lib.gleam", 98). ?DOC(false). -spec flag( binary(), list(binary()), binary(), binary(), flag_decoder(IIG), fun((IIG) -> action_decoder(III)) ) -> action_decoder(III). flag(Name, Aliases, Value_type, Description, Decoder, Then) -> Default_value = erlang:element(2, Decoder), Action_decoder = Then(Default_value), Decode_fn = fun(Args) -> {Arg_name, Value} = begin _pipe = [Name | Aliases], _pipe@1 = get_argument(_pipe, Args), _pipe@2 = gleam@option:map( _pipe@1, fun(Opt) -> {erlang:element(1, Opt), {some, erlang:element(2, Opt)}} end ), gleam@option:unwrap(_pipe@2, {Name, none}) end, {Value@1, Errs} = begin _pipe@3 = (erlang:element(3, Decoder))(Value), _pipe@4 = gleam@result:map_error( _pipe@3, fun(Err) -> [{parse_error, Err, Arg_name}] end ), result_to_tuple(_pipe@4, Default_value) end, {Value@2, Other_errs} = (erlang:element(4, Then(Value@1)))(Args), {Value@2, lists:append(Errs, Other_errs)} end, Flag = {flag, Name, Aliases, Description, Value_type}, {action_decoder, erlang:element(2, Action_decoder), [Flag | erlang:element(3, Action_decoder)], Decode_fn}. -file("src/cigogne/internal/cli_lib.gleam", 154). ?DOC(false). -spec tuple_to_result({IIX, list(IIY)}) -> {ok, IIX} | {error, list(IIY)}. tuple_to_result(Value) -> case erlang:element(2, Value) of [] -> {ok, erlang:element(1, Value)}; _ = Errs -> {error, Errs} end. -file("src/cigogne/internal/cli_lib.gleam", 194). ?DOC(false). -spec decode_string(gleam@option:option(list(binary()))) -> {ok, gleam@option:option(binary())} | {error, binary()}. decode_string(Values) -> case Values of none -> {ok, none}; {some, []} -> {error, <<"No value provided"/utf8>>}; {some, [V | _]} -> {ok, {some, V}} end. -file("src/cigogne/internal/cli_lib.gleam", 217). ?DOC(false). -spec map(flag_decoder(IJV), fun((IJV) -> IJX)) -> flag_decoder(IJX). map(Flag_decoder, Map_fn) -> Decode_fn = fun(Values) -> _pipe = (erlang:element(3, Flag_decoder))(Values), gleam@result:map(_pipe, Map_fn) end, {flag_decoder, Map_fn(erlang:element(2, Flag_decoder)), Decode_fn}. -file("src/cigogne/internal/cli_lib.gleam", 226). ?DOC(false). -spec then(flag_decoder(IJZ), IKB, fun((IJZ) -> {ok, IKB} | {error, binary()})) -> flag_decoder(IKB). then(Flag_decoder, Default_value, Then_fn) -> Decode_fn = fun(Values) -> _pipe = (erlang:element(3, Flag_decoder))(Values), gleam@result:'try'(_pipe, Then_fn) end, {flag_decoder, Default_value, Decode_fn}. -file("src/cigogne/internal/cli_lib.gleam", 204). ?DOC(false). -spec required(flag_decoder(gleam@option:option(IJR)), IJR) -> flag_decoder(IJR). required(Flag_decoder, Default_value) -> _pipe = Flag_decoder, then(_pipe, Default_value, fun(Opt_value) -> case Opt_value of none -> {error, <<"This argument is required !"/utf8>>}; {some, V} -> {ok, V} end end). -file("src/cigogne/internal/cli_lib.gleam", 353). ?DOC(false). -spec box_lines(list(binary()), list(binary())) -> list(binary()). box_lines(Lines, Boxed) -> case Lines of [] -> Boxed; [Line | Rest] -> box_lines( Rest, [<<<<"= "/utf8, Line/binary>>/binary, " ="/utf8>> | Boxed] ) end. -file("src/cigogne/internal/cli_lib.gleam", 404). ?DOC(false). -spec print_errors(list(parse_error())) -> nil. print_errors(Err) -> gleam@list:each( Err, fun(Error) -> gleam_stdlib:println_error( <<<<<<"[Argument "/utf8, (erlang:element(3, Error))/binary>>/binary, "] "/utf8>>/binary, (erlang:element(2, Error))/binary>> ) end ), gleam_stdlib:println_error(<<""/utf8>>). -file("src/cigogne/internal/cli_lib.gleam", 426). ?DOC(false). -spec get_action_args(list(binary()), list(binary())) -> {ok, list(binary())} | {error, nil}. get_action_args(Action_path, Args) -> case {Action_path, Args} of {[], Args_rest} -> {ok, Args_rest}; {[Head | Tail], [Head2 | Tail2]} when Head =:= Head2 -> get_action_args(Tail, Tail2); {_, _} -> {error, nil} end. -file("src/cigogne/internal/cli_lib.gleam", 411). ?DOC(false). -spec find_action(list(action(ILC)), list(binary())) -> {ok, {action(ILC), list(binary())}} | {error, nil}. find_action(Actions_to_try, Args) -> case Actions_to_try of [] -> {error, nil}; [Action | Rest] -> case get_action_args(erlang:element(2, Action), Args) of {ok, Action_args} -> {ok, {Action, Action_args}}; {error, _} -> find_action(Rest, Args) end end. -file("src/cigogne/internal/cli_lib.gleam", 461). ?DOC(false). -spec add_to_dict( gleam@dict:dict(binary(), list(binary())), {binary(), gleam@option:option(binary())} ) -> gleam@dict:dict(binary(), list(binary())). add_to_dict(Dict, Kv) -> {Key, Value} = Kv, _pipe = Dict, gleam@dict:upsert(_pipe, Key, fun(Prev_v) -> case {Prev_v, Value} of {none, none} -> []; {none, {some, V}} -> [V]; {{some, Prev_v@1}, none} -> Prev_v@1; {{some, Prev_v@2}, {some, V@1}} -> [V@1 | Prev_v@2] end end). -file("src/cigogne/internal/cli_lib.gleam", 442). ?DOC(false). -spec args_list_to_dict( list(binary()), gleam@dict:dict(binary(), list(binary())) ) -> gleam@dict:dict(binary(), list(binary())). args_list_to_dict(Args, Dict) -> case Args of [] -> Dict; [<<"--"/utf8, Name/binary>>] -> _pipe = Dict, add_to_dict(_pipe, {Name, none}); [<<"-"/utf8, Name/binary>>] -> _pipe = Dict, add_to_dict(_pipe, {Name, none}); [_] -> Dict; [<<"--"/utf8, Name@1/binary>>, <<"-"/utf8, Arg2/binary>> | Rest] -> args_list_to_dict( [<<"-"/utf8, Arg2/binary>> | Rest], begin _pipe@1 = Dict, add_to_dict(_pipe@1, {Name@1, none}) end ); [<<"-"/utf8, Name@1/binary>>, <<"-"/utf8, Arg2/binary>> | Rest] -> args_list_to_dict( [<<"-"/utf8, Arg2/binary>> | Rest], begin _pipe@1 = Dict, add_to_dict(_pipe@1, {Name@1, none}) end ); [<<"--"/utf8, Name@2/binary>>, Arg2@1 | Rest@1] -> args_list_to_dict( Rest@1, begin _pipe@2 = Dict, add_to_dict(_pipe@2, {Name@2, {some, Arg2@1}}) end ); [<<"-"/utf8, Name@2/binary>>, Arg2@1 | Rest@1] -> args_list_to_dict( Rest@1, begin _pipe@2 = Dict, add_to_dict(_pipe@2, {Name@2, {some, Arg2@1}}) end ); [_ | Rest@2] -> args_list_to_dict(Rest@2, Dict) end. -file("src/cigogne/internal/cli_lib.gleam", 438). ?DOC(false). -spec args_to_dict(list(binary())) -> gleam@dict:dict(binary(), list(binary())). args_to_dict(Args) -> args_list_to_dict(Args, maps:new()). -file("src/cigogne/internal/cli_lib.gleam", 167). ?DOC(false). -spec decode_bool(gleam@option:option(list(binary()))) -> {ok, boolean()} | {error, binary()}. decode_bool(Values) -> case Values of none -> {ok, false}; {some, []} -> {ok, true}; {some, [V | _]} -> case string:lowercase(V) of <<"true"/utf8>> -> {ok, true}; <<"1"/utf8>> -> {ok, true}; <<"yes"/utf8>> -> {ok, true}; <<"false"/utf8>> -> {ok, false}; <<"0"/utf8>> -> {ok, false}; <<"no"/utf8>> -> {ok, false}; _ -> {error, <<<<"Expected a boolean, got '"/utf8, V/binary>>/binary, "'"/utf8>>} end end. -file("src/cigogne/internal/cli_lib.gleam", 327). ?DOC(false). -spec print_flag(binary()) -> binary(). print_flag(Flag_name) -> case string:length(Flag_name) of 0 -> <<"/!\\ Flag name should not be empty"/utf8>>; 1 -> <<"-"/utf8, Flag_name/binary>>; _ -> <<"--"/utf8, Flag_name/binary>> end. -file("src/cigogne/internal/cli_lib.gleam", 335). ?DOC(false). -spec justify_left(binary(), integer()) -> binary(). justify_left(Text, Width) -> case string:length(Text) of I when I < Width -> <>, Width - I))/binary>>; _ -> Text end. -file("src/cigogne/internal/cli_lib.gleam", 381). ?DOC(false). -spec do_padding(binary(), integer()) -> binary(). do_padding(Text, Width) -> Padding = Width - string:length(Text), Left_padding = Padding div 2, Right_padding = Padding - Left_padding, Left_spaces = gleam@string:repeat(<<" "/utf8>>, Left_padding), Right_spaces = gleam@string:repeat(<<" "/utf8>>, Right_padding), <<<>/binary, Right_spaces/binary>>. -file("src/cigogne/internal/cli_lib.gleam", 390). ?DOC(false). -spec words_to_lines(list(binary()), integer()) -> list(binary()). words_to_lines(Words, Max_line_length) -> _pipe = gleam@list:fold(Words, [], fun(Acc, Word) -> case Acc of [] -> [Word]; [Last_line | _] -> case string:length(Last_line) + string:length(Word) of Len when Len =< Max_line_length -> [<<<>/binary, Word/binary>> | Acc]; _ -> [Word, Last_line | Acc] end end end), lists:reverse(_pipe). -file("src/cigogne/internal/cli_lib.gleam", 180). ?DOC(false). -spec decode_int(gleam@option:option(list(binary()))) -> {ok, gleam@option:option(integer())} | {error, binary()}. decode_int(Values) -> case Values of none -> {ok, none}; {some, []} -> {error, <<"No value provided"/utf8>>}; {some, [V | _]} -> case gleam_stdlib:parse_int(V) of {ok, V@1} -> {ok, {some, V@1}}; {error, _} -> {error, <<<<"Expected an integer, got '"/utf8, V/binary>>/binary, "'"/utf8>>} end end. -file("src/cigogne/internal/cli_lib.gleam", 360). ?DOC(false). -spec center_text(binary(), integer()) -> binary(). center_text(Text, Max_width) -> Lines = gleam@string:split(Text, <<"\n"/utf8>>), Max_line_length = begin _pipe = gleam@list:fold( Lines, 0, fun(Acc, Line) -> gleam@int:max(Acc, string:length(Line)) end ), gleam@int:min(_pipe, Max_width) end, _pipe@1 = Lines, _pipe@4 = gleam@list:flat_map( _pipe@1, fun(Line@1) -> Line_length = string:length(Line@1), case Line_length of V when V > Max_line_length -> _pipe@2 = gleam@string:split(Line@1, <<" "/utf8>>), _pipe@3 = words_to_lines(_pipe@2, Max_line_length), gleam@list:map( _pipe@3, fun(_capture) -> do_padding(_capture, Max_line_length) end ); _ -> [do_padding(Line@1, Max_line_length)] end end ), gleam@string:join(_pipe@4, <<"\n"/utf8>>). -file("src/cigogne/internal/cli_lib.gleam", 342). ?DOC(false). -spec box_text(binary(), integer()) -> binary(). box_text(Text, Max_width) -> Lines = begin _pipe = center_text(Text, Max_width - 4), gleam@string:split(_pipe, <<"\n"/utf8>>) end, Actual_width = string:length( begin _pipe@1 = Lines, _pipe@2 = gleam@list:first(_pipe@1), gleam@result:unwrap(_pipe@2, <<""/utf8>>) end ) + 4, Top_bottom_line = gleam@string:repeat(<<"="/utf8>>, Actual_width), _pipe@3 = box_lines(Lines, [Top_bottom_line]), _pipe@4 = gleam@list:prepend(_pipe@3, Top_bottom_line), _pipe@5 = lists:reverse(_pipe@4), gleam@string:join(_pipe@5, <<"\n"/utf8>>). -file("src/cigogne/internal/cli_lib.gleam", 284). ?DOC(false). -spec print_help(command(any())) -> nil. print_help(Command) -> _pipe = (<<<<(erlang:element(2, Command))/binary, "\n"/utf8>>/binary, (erlang:element(3, Command))/binary>>), _pipe@1 = box_text(_pipe, 80), gleam_stdlib:println(_pipe@1), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println( <<<<"Usage: gleam run -m "/utf8, (erlang:element(2, Command))/binary>>/binary, " []"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Available actions:"/utf8>>), gleam@list:each( begin _pipe@2 = erlang:element(4, Command), lists:reverse(_pipe@2) end, fun(Action) -> Action_path = begin _pipe@3 = erlang:element(2, Action), gleam@string:join(_pipe@3, <<" "/utf8>>) end, gleam_stdlib:println( <<<<<<" "/utf8, Action_path/binary>>/binary, " - "/utf8>>/binary, (erlang:element(3, Action))/binary>> ) end ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println( <<<<"Use `"/utf8, (erlang:element(2, Command))/binary>>/binary, " help ` to get more information about an action."/utf8>> ). -file("src/cigogne/internal/cli_lib.gleam", 306). ?DOC(false). -spec print_help_action(action(any())) -> nil. print_help_action(Action) -> _pipe@1 = (<<<<(begin _pipe = erlang:element(2, Action), gleam@string:join(_pipe, <<" "/utf8>>) end)/binary, "\n"/utf8>>/binary, (erlang:element(3, Action))/binary>>), _pipe@2 = box_text(_pipe@1, 80), gleam_stdlib:println(_pipe@2), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Available flags:"/utf8>>), gleam@list:each( erlang:element(3, erlang:element(4, Action)), fun(Flag) -> _pipe@5 = (<<<<<<<<<<<<(justify_left( <<<<(print_flag(erlang:element(2, Flag)))/binary, " "/utf8>>/binary, (erlang:element(5, Flag))/binary>>, 20 ))/binary, " - "/utf8>>/binary, (erlang:element(4, Flag))/binary>>/binary, "\n"/utf8>>/binary, (gleam@string:repeat(<<" "/utf8>>, 24))/binary>>/binary, "Aliases: "/utf8>>/binary, (begin _pipe@3 = erlang:element(3, Flag), _pipe@4 = gleam@list:map(_pipe@3, fun print_flag/1), gleam@string:join(_pipe@4, <<", "/utf8>>) end)/binary>>), gleam_stdlib:println(_pipe@5) end ). -file("src/cigogne/internal/cli_lib.gleam", 258). ?DOC(false). -spec help_actions( command(IKK), list(binary()), fun(() -> {ok, IKK} | {error, nil}) ) -> {ok, IKK} | {error, nil}. help_actions(Command, Args, Exec_action) -> case Args of [<<"help"/utf8>>] -> print_help(Command), {error, nil}; [<<"--help"/utf8>>] -> print_help(Command), {error, nil}; [<<"help"/utf8>> | Action_args] -> case find_action(erlang:element(4, Command), Action_args) of {ok, {Action, _}} -> print_help_action(Action), {error, nil}; {error, _} -> print_help(Command), {error, nil} end; _ -> Exec_action() end. -file("src/cigogne/internal/cli_lib.gleam", 239). ?DOC(false). -spec run(command(IKF), list(binary())) -> {ok, IKF} | {error, nil}. run(Command, Args) -> help_actions( Command, Args, fun() -> case find_action(erlang:element(4, Command), Args) of {ok, {Action, Args@1}} -> _pipe = args_to_dict(Args@1), _pipe@1 = (erlang:element(4, erlang:element(4, Action)))( _pipe ), _pipe@2 = tuple_to_result(_pipe@1), gleam@result:map_error( _pipe@2, fun(Err) -> print_errors(Err), print_help(Command) end ); {error, _} -> print_help(Command), {error, nil} end end ).