Current section

Files

Jump to
glint src glint@flag.erl
Raw

src/glint@flag.erl

-module(glint@flag).
-compile(no_auto_import).
-export([int/2, float/2, float_list/2, int_list/2, string/2, string_list/2, bool/2, build_map/1, update_flags/2]).
-export_type([flag_value/0, flag/0]).
-type flag_value() :: {b, boolean()} |
{i, integer()} |
{li, list(integer())} |
{f, float()} |
{lf, list(float())} |
{s, binary()} |
{ls, list(binary())}.
-type flag() :: {flag, binary(), flag_value()}.
-spec int(binary(), integer()) -> flag().
int(Name, Value) ->
{flag, Name, {i, Value}}.
-spec float(binary(), float()) -> flag().
float(Name, Value) ->
{flag, Name, {f, Value}}.
-spec float_list(binary(), list(float())) -> flag().
float_list(Name, Value) ->
{flag, Name, {lf, Value}}.
-spec int_list(binary(), list(integer())) -> flag().
int_list(Name, Value) ->
{flag, Name, {li, Value}}.
-spec string(binary(), binary()) -> flag().
string(Name, Value) ->
{flag, Name, {s, Value}}.
-spec string_list(binary(), list(binary())) -> flag().
string_list(Name, Value) ->
{flag, Name, {ls, Value}}.
-spec bool(binary(), boolean()) -> flag().
bool(Name, Value) ->
{flag, Name, {b, Value}}.
-spec build_map(list(flag())) -> gleam@map:map_(binary(), flag_value()).
build_map(Flags) ->
gleam@list:fold(
Flags,
gleam@map:new(),
fun(M, Flag) ->
gleam@map:insert(
M,
erlang:element(2, Flag),
erlang:element(3, Flag)
)
end
).
-spec update_flags(gleam@map:map_(binary(), flag_value()), binary()) -> {ok,
gleam@map:map_(binary(), flag_value())} |
{error, snag:snag()}.
update_flags(Flags, Flag_input) ->
Flag_input@1 = gleam@string:drop_left(Flag_input, 2),
case begin
_pipe = Flag_input@1,
_pipe@1 = gleam@string:split_once(_pipe, <<"="/utf8>>),
gleam@result:replace_error(_pipe@1, no_value_flag_err(Flag_input@1))
end of
{error, _try} -> {error, _try};
{ok, {Key, Value}} ->
case begin
_pipe@2 = gleam@map:get(Flags, Key),
gleam@result:replace_error(_pipe@2, undefined_flag_err(Key))
end of
{error, _try@1} -> {error, _try@1};
{ok, Default} ->
_pipe@3 = case Default of
{i, _@1} ->
fun parse_int/2;
{li, _@2} ->
fun parse_int_list/2;
{f, _@3} ->
fun parse_float/2;
{lf, _@4} ->
fun parse_float_list/2;
{s, _@5} ->
fun parse_string/2;
{ls, _@6} ->
fun parse_string_list/2;
{b, _@7} ->
fun parse_bool/2
end(Key, Value),
gleam@result:map(
_pipe@3,
fun(_capture) ->
gleam@map:insert(Flags, Key, _capture)
end
)
end
end.
-spec parse_int(binary(), binary()) -> {ok, flag_value()} | {error, snag:snag()}.
parse_int(Key, Value) ->
_pipe = parse_flag(Value, fun gleam@int:parse/1, fun(A) -> {i, A} end),
gleam@result:replace_error(_pipe, cannot_parse(Key, Value, <<"int"/utf8>>)).
-spec parse_int_list(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_int_list(Key, Value) ->
_pipe = parse_list_flag(Value, fun gleam@int:parse/1, fun(A) -> {li, A} end),
gleam@result:replace_error(
_pipe,
cannot_parse(Key, Value, <<"int list"/utf8>>)
).
-spec parse_float(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_float(Key, Value) ->
_pipe = parse_flag(Value, fun gleam@float:parse/1, fun(A) -> {f, A} end),
gleam@result:replace_error(
_pipe,
cannot_parse(Key, Value, <<"float"/utf8>>)
).
-spec parse_float_list(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_float_list(Key, Value) ->
_pipe = parse_list_flag(
Value,
fun gleam@float:parse/1,
fun(A) -> {lf, A} end
),
gleam@result:replace_error(
_pipe,
cannot_parse(Key, Value, <<"float list"/utf8>>)
).
-spec parse_bool(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_bool(Key, Value) ->
case Value of
<<"true"/utf8>> ->
{ok, {b, true}};
<<"false"/utf8>> ->
{ok, {b, false}};
_@1 ->
{error, cannot_parse(Key, Value, <<"bool"/utf8>>)}
end.
-spec parse_string(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_string(_, Value) ->
parse_flag(Value, fun(A) -> {ok, A} end, fun(A) -> {s, A} end).
-spec parse_string_list(binary(), binary()) -> {ok, flag_value()} |
{error, snag:snag()}.
parse_string_list(_, Value) ->
parse_list_flag(Value, fun(A) -> {ok, A} end, fun(A) -> {ls, A} end).
-spec parse_flag(
binary(),
fun((binary()) -> {ok, EGC} | {error, EGD}),
fun((EGC) -> flag_value())
) -> {ok, flag_value()} | {error, EGD}.
parse_flag(Value, Parse, Construct) ->
_pipe = Value,
_pipe@1 = Parse(_pipe),
gleam@result:map(_pipe@1, Construct).
-spec parse_list_flag(
binary(),
fun((binary()) -> {ok, EGI} | {error, EGJ}),
fun((list(EGI)) -> flag_value())
) -> {ok, flag_value()} | {error, EGJ}.
parse_list_flag(Value, Parse, Construct) ->
_pipe = Value,
_pipe@1 = gleam@string:split(_pipe, <<","/utf8>>),
_pipe@2 = gleam@list:try_map(_pipe@1, Parse),
gleam@result:map(_pipe@2, Construct).
-spec layer_invalid_flag(snag:snag(), binary()) -> snag:snag().
layer_invalid_flag(Err, Flag) ->
_pipe = [<<"invalid flag '"/utf8>>, Flag, <<"'"/utf8>>],
_pipe@1 = gleam@string:concat(_pipe),
snag:layer(Err, _pipe@1).
-spec no_value_flag_err(binary()) -> snag:snag().
no_value_flag_err(Flag_input) ->
_pipe = [<<"flag '"/utf8>>, Flag_input, <<"' has no assigned value"/utf8>>],
_pipe@1 = gleam@string:concat(_pipe),
_pipe@2 = snag:new(_pipe@1),
layer_invalid_flag(_pipe@2, Flag_input).
-spec undefined_flag_err(binary()) -> snag:snag().
undefined_flag_err(Key) ->
_pipe = <<"flag provided but not defined"/utf8>>,
_pipe@1 = snag:new(_pipe),
layer_invalid_flag(_pipe@1, Key).
-spec cannot_parse(binary(), binary(), binary()) -> snag:snag().
cannot_parse(Key, Value, Kind) ->
_pipe = [<<"cannot parse flag '"/utf8>>,
Key,
<<"' value '"/utf8>>,
Value,
<<"' as "/utf8>>,
Kind],
_pipe@1 = gleam@string:concat(_pipe),
_pipe@2 = snag:new(_pipe@1),
layer_invalid_flag(_pipe@2, Key).