Current section
Files
Jump to
Current section
Files
src/clip@arg.erl
-module(clip@arg).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/clip/arg.gleam").
-export([to_arg_info/1, to_arg_info_many/1, to_arg_info_many1/1, try_map/2, map/2, default/2, optional/1, help/2, int/1, float/1, new/1, run/2, run_many/2, run_many1/2]).
-export_type([arg/1]).
-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(" Functions for building `Arg`s. An `Arg` is a positional option.\n").
-opaque arg(NQE) :: {arg,
binary(),
gleam@option:option(NQE),
gleam@option:option(binary()),
fun((binary()) -> {ok, NQE} | {error, binary()})}.
-file("src/clip/arg.gleam", 23).
-spec pos_info(arg(any())) -> clip@arg_info:positional_info().
pos_info(Arg) ->
{positional_info,
erlang:element(2, Arg),
begin
_pipe = erlang:element(3, Arg),
gleam@option:map(_pipe, fun gleam@string:inspect/1)
end,
erlang:element(4, Arg),
no_repeat}.
-file("src/clip/arg.gleam", 33).
?DOC(" Used internally, not intended for direct usage.\n").
-spec to_arg_info(arg(any())) -> clip@arg_info:arg_info().
to_arg_info(Arg) ->
_record = clip@arg_info:empty(),
{arg_info,
erlang:element(2, _record),
[pos_info(Arg)],
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/clip/arg.gleam", 38).
?DOC(" Used internally, not intended for direct usage.\n").
-spec to_arg_info_many(arg(any())) -> clip@arg_info:arg_info().
to_arg_info_many(Arg) ->
_record = clip@arg_info:empty(),
{arg_info,
erlang:element(2, _record),
[begin
_record@1 = pos_info(Arg),
{positional_info,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
many_repeat}
end],
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/clip/arg.gleam", 45).
?DOC(" Used internally, not intended for direct usage.\n").
-spec to_arg_info_many1(arg(any())) -> clip@arg_info:arg_info().
to_arg_info_many1(Arg) ->
_record = clip@arg_info:empty(),
{arg_info,
erlang:element(2, _record),
[begin
_record@1 = pos_info(Arg),
{positional_info,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
many1_repeat}
end],
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/clip/arg.gleam", 65).
?DOC(
" Modify the value produced by an `Arg` in a way that may fail.\n"
"\n"
" ```gleam\n"
" arg.new(\"age\")\n"
" |> arg.try_map(fn(age_str) {\n"
" case int.parse(age_str) {\n"
" Ok(age) -> Ok(age)\n"
" Error(Nil) -> Error(\"Unable to parse integer\")\n"
" }\n"
" })\n"
" ```\n"
"\n"
" Note: `try_map` can change the type of an `Arg` and therefore clears any\n"
" previously set default value.\n"
).
-spec try_map(arg(NQN), fun((NQN) -> {ok, NQP} | {error, binary()})) -> arg(NQP).
try_map(Arg, F) ->
{arg,
erlang:element(2, Arg),
none,
erlang:element(4, Arg),
fun(V) ->
gleam@result:'try'((erlang:element(5, Arg))(V), fun(A) -> F(A) end)
end}.
-file("src/clip/arg.gleam", 81).
?DOC(
" Modify the value produced by an `Arg` in a way that cannot fail.\n"
"\n"
" ```gleam\n"
" arg.new(\"name\")\n"
" |> arg.map(fn(name) { string.uppercase(name) })\n"
" ```\n"
"\n"
" Note: `map` can change the type of an `Arg` and therefore clears any\n"
" previously set default value.\n"
).
-spec map(arg(NQT), fun((NQT) -> NQV)) -> arg(NQV).
map(Arg, F) ->
try_map(Arg, fun(A) -> {ok, F(A)} end).
-file("src/clip/arg.gleam", 91).
?DOC(" Provide a default value for an `Arg` when it is not provided by the user.\n").
-spec default(arg(NRC), NRC) -> arg(NRC).
default(Arg, Default) ->
{arg,
erlang:element(2, Arg),
{some, Default},
erlang:element(4, Arg),
erlang:element(5, Arg)}.
-file("src/clip/arg.gleam", 86).
?DOC(" Transform an `Arg(a)` to an `Arg(Result(a, Nil)`, making it optional.\n").
-spec optional(arg(NQX)) -> arg({ok, NQX} | {error, nil}).
optional(Arg) ->
_pipe = Arg,
_pipe@1 = map(_pipe, fun(Field@0) -> {ok, Field@0} end),
default(_pipe@1, {error, nil}).
-file("src/clip/arg.gleam", 96).
?DOC(" Add help text to an `Arg`.\n").
-spec help(arg(NRF), binary()) -> arg(NRF).
help(Arg, Help) ->
{arg,
erlang:element(2, Arg),
erlang:element(3, Arg),
{some, Help},
erlang:element(5, Arg)}.
-file("src/clip/arg.gleam", 109).
?DOC(
" Modify an `Arg(String)` to produce an `Int`.\n"
"\n"
" ```gleam\n"
" arg.new(\"age\")\n"
" |> arg.int\n"
" ```\n"
"\n"
" Note: `int` changes the type of an `Arg` and therefore clears any\n"
" previously set default value.\n"
).
-spec int(arg(binary())) -> arg(integer()).
int(Arg) ->
_pipe = Arg,
try_map(_pipe, fun(Val) -> _pipe@1 = gleam_stdlib:parse_int(Val),
gleam@result:map_error(
_pipe@1,
fun(_) ->
<<"Non-integer value provided for "/utf8,
(erlang:element(2, Arg))/binary>>
end
) end).
-file("src/clip/arg.gleam", 126).
?DOC(
" Modify an `Arg(String)` to produce a `Float`.\n"
"\n"
" ```gleam\n"
" arg.new(\"height\")\n"
" |> arg.float\n"
" ```\n"
"\n"
" Note: `float` changes the type of an `Arg` and therefore clears any\n"
" previously set default value.\n"
).
-spec float(arg(binary())) -> arg(float()).
float(Arg) ->
_pipe = Arg,
try_map(_pipe, fun(Val) -> _pipe@1 = gleam_stdlib:parse_float(Val),
gleam@result:map_error(
_pipe@1,
fun(_) ->
<<"Non-float value provided for "/utf8,
(erlang:element(2, Arg))/binary>>
end
) end).
-file("src/clip/arg.gleam", 137).
?DOC(
" Create a new `Arg` with the provided name. New `Arg`s always initially\n"
" produce a `String`, which is the unmodified value given by the user on the\n"
" command line.\n"
).
-spec new(binary()) -> arg(binary()).
new(Name) ->
{arg, Name, none, none, fun(Field@0) -> {ok, Field@0} end}.
-file("src/clip/arg.gleam", 141).
-spec not_num(binary()) -> boolean().
not_num(Str) ->
Result = begin
_pipe = gleam_stdlib:parse_int(Str),
gleam@result:is_ok(_pipe)
end
orelse begin
_pipe@1 = gleam_stdlib:parse_float(Str),
gleam@result:is_ok(_pipe@1)
end,
not Result.
-file("src/clip/arg.gleam", 147).
-spec run_aux(boolean(), arg(NRN), list(binary())) -> {ok,
{NRN, list(binary())}} |
{error, binary()}.
run_aux(Strict, Arg, Args) ->
case {Args, erlang:element(3, Arg)} of
{[<<"--"/utf8>> | Rest], _} ->
_pipe = run_aux(false, Arg, Rest),
gleam@result:map(
_pipe,
fun(V) ->
{erlang:element(1, V),
[<<"--"/utf8>> | erlang:element(2, V)]}
end
);
{[Head | Rest@1], _} ->
case (Strict andalso gleam_stdlib:string_starts_with(
Head,
<<"-"/utf8>>
))
andalso not_num(Head) of
true ->
_pipe@1 = run_aux(Strict, Arg, Rest@1),
gleam@result:map(
_pipe@1,
fun(V@1) ->
{erlang:element(1, V@1),
[Head | erlang:element(2, V@1)]}
end
);
false ->
gleam@result:'try'(
(erlang:element(5, Arg))(Head),
fun(A) -> {ok, {A, Rest@1}} end
)
end;
{[], {some, V@2}} ->
{ok, {V@2, []}};
{[], none} ->
{error,
<<"missing required arg: "/utf8,
(erlang:element(2, Arg))/binary>>}
end.
-file("src/clip/arg.gleam", 174).
?DOC(
" Run an `Arg(a)` against a list of arguments. Used internally by `clip`, not\n"
" intended for direct usage.\n"
).
-spec run(arg(NRT), list(binary())) -> {ok, {NRT, list(binary())}} |
{error, binary()}.
run(Arg, Args) ->
run_aux(true, Arg, Args).
-file("src/clip/arg.gleam", 181).
-spec run_many_aux(list(NRZ), arg(NRZ), list(binary())) -> {ok,
{list(NRZ), list(binary())}} |
{error, binary()}.
run_many_aux(Acc, Arg, Args) ->
case Args of
[] ->
{ok, {lists:reverse(Acc), []}};
_ ->
case run(Arg, Args) of
{ok, {A, Rest}} ->
run_many_aux([A | Acc], Arg, Rest);
{error, _} ->
{ok, {lists:reverse(Acc), Args}}
end
end.
-file("src/clip/arg.gleam", 198).
?DOC(
" Run an `Arg(a)` against a list of arguments producing zero or more results.\n"
" Used internally by `clip`, not intended for direct usage.\n"
).
-spec run_many(arg(NSH), list(binary())) -> {ok, {list(NSH), list(binary())}} |
{error, binary()}.
run_many(Arg, Args) ->
run_many_aux([], Arg, Args).
-file("src/clip/arg.gleam", 207).
?DOC(
" Run an `Arg(a)` against a list of arguments producing one or more results.\n"
" Used internally by `clip`, not intended for direct usage.\n"
).
-spec run_many1(arg(NSO), list(binary())) -> {ok, {list(NSO), list(binary())}} |
{error, binary()}.
run_many1(Arg, Args) ->
gleam@result:'try'(
run_many_aux([], Arg, Args),
fun(_use0) ->
{Vs, Rest} = _use0,
case Vs of
[] ->
{error,
<<"must provide at least one valid value for: "/utf8,
(erlang:element(2, Arg))/binary>>};
_ ->
{ok, {Vs, Rest}}
end
end
).