Current section
Files
Jump to
Current section
Files
gen/src/qs.erl
-module(qs).
-compile(no_auto_import).
-export([parse_key_value/1, parse/1, serialize/1, empty/0, get/2, get_as_string/2, get_as_bool/2, get_as_int/2, get_as_float/2, get_as_list/2, get_as_list_of_bool/2, get_as_list_of_int/2, get_as_list_of_float/2, maybe_get_as_list/2, has_key/2, insert/3, insert_one/3, insert_list/3, push/3, merge/2, delete/2]).
-export_type([one_or_many/0]).
-type one_or_many() :: {one, binary()} | {many, list(binary())}.
-spec parse_key_value(binary()) -> {ok, {binary(), binary(), boolean()}} |
{error, binary()}.
parse_key_value(Segment) ->
gleam@result:replace_error(
gleam@result:map(
gleam@string:split_once(
gleam@result:unwrap(gleam@uri:percent_decode(Segment), Segment),
<<"="/utf8>>
),
fun(Pair) ->
{K, V} = Pair,
case gleam@string:ends_with(K, <<"[]"/utf8>>) of
true ->
{gleam@string:replace(K, <<"[]"/utf8>>, <<""/utf8>>),
V,
true};
false ->
{K, V, false}
end
end
),
gleam@string:append(<<"Unable to parse "/utf8>>, Segment)
).
-spec parse(binary()) -> {ok, gleam@map:map_(binary(), one_or_many())} |
{error, binary()}.
parse(Qs) ->
case gleam@result:all(
gleam@list:map(
gleam@string:split(
gleam@string:replace(Qs, <<"?"/utf8>>, <<""/utf8>>),
<<"&"/utf8>>
),
fun parse_key_value/1
)
) of
{error, Gleam@try_error} -> {error, Gleam@try_error};
{ok, Segments} ->
{ok,
gleam@map:map_values(
gleam@list:fold(Segments, empty(), fun add_segment/2),
fun reverse_many/2
)}
end.
-spec add_segment(
{binary(), binary(), boolean()},
gleam@map:map_(binary(), one_or_many())
) -> gleam@map:map_(binary(), one_or_many()).
add_segment(Segment, Query) ->
{Key, Value, Is_list} = Segment,
Updater = fun(Res) -> case Res of
{ok, Existing} ->
case Is_list of
true ->
case Existing of
{one, _} ->
{many, [Value]};
{many, Existing_list} ->
{many, [Value | Existing_list]}
end;
false ->
{one, Value}
end;
{error, _} ->
case Is_list of
true ->
{many, [Value]};
false ->
{one, Value}
end
end end,
gleam@map:update(Query, Key, Updater).
-spec reverse_many(binary(), one_or_many()) -> one_or_many().
reverse_many(_, V) ->
case V of
{many, Values} ->
{many, gleam@list:reverse(Values)};
_ ->
V
end.
-spec serialize(gleam@map:map_(binary(), one_or_many())) -> binary().
serialize(Query) ->
add_question_mark(
gleam@string:join(
gleam@list:flatten(
gleam@list:map(gleam@map:to_list(Query), fun serialize_key/1)
),
<<"&"/utf8>>
)
).
-spec serialize_key({binary(), one_or_many()}) -> list(binary()).
serialize_key(Input) ->
{Key, One_or_many} = Input,
case One_or_many of
{one, Value} ->
[join_key_value(Key, Value, <<"="/utf8>>)];
{many, Values} ->
gleam@list:map(
Values,
fun(Gleam@capture_variable) ->
join_key_value(Key, Gleam@capture_variable, <<"[]="/utf8>>)
end
)
end.
-spec join_key_value(binary(), binary(), binary()) -> binary().
join_key_value(Key, Value, Join) ->
gleam@string:append(
gleam@string:append(gleam@uri:percent_encode(Key), Join),
gleam@uri:percent_encode(Value)
).
-spec add_question_mark(binary()) -> binary().
add_question_mark(Query) ->
gleam@string:append(<<"?"/utf8>>, Query).
-spec empty() -> gleam@map:map_(binary(), one_or_many()).
empty() ->
gleam@map:new().
-spec get(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
one_or_many()} |
{error, binary()}.
get(Query, Key) ->
Error = gleam@string:append(<<"Invalid key "/utf8>>, Key),
gleam@result:replace_error(gleam@map:get(Query, Key), Error).
-spec get_as_string(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
binary()} |
{error, binary()}.
get_as_string(Query, Key) ->
case get(Query, Key) of
{error, Gleam@try_error} -> {error, Gleam@try_error};
{ok, One_or_many} ->
case One_or_many of
{one, Value} ->
{ok, Value};
{many, _} ->
{error, gleam@string:append(Key, <<" is a list"/utf8>>)}
end
end.
-spec get_as_bool(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
boolean()} |
{error, binary()}.
get_as_bool(Query, Key) ->
gleam@result:then(get_as_string(Query, Key), fun parse_bool/1).
-spec get_as_int(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
integer()} |
{error, binary()}.
get_as_int(Query, Key) ->
case get_as_string(Query, Key) of
{error, Gleam@try_error} -> {error, Gleam@try_error};
{ok, Value} ->
gleam@result:replace_error(
gleam@int:parse(Value),
gleam@string:append(<<"Invalid Int "/utf8>>, Value)
)
end.
-spec get_as_float(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
float()} |
{error, binary()}.
get_as_float(Query, Key) ->
case get_as_string(Query, Key) of
{error, Gleam@try_error} -> {error, Gleam@try_error};
{ok, Value} ->
gleam@result:replace_error(
gleam@float:parse(Value),
gleam@string:append(<<"Invalid Float "/utf8>>, Value)
)
end.
-spec get_as_list(gleam@map:map_(binary(), one_or_many()), binary()) -> list(binary()).
get_as_list(Query, Key) ->
gleam@result:unwrap(maybe_get_as_list(Query, Key), []).
-spec get_as_list_of_bool(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
list(boolean())} |
{error, binary()}.
get_as_list_of_bool(Query, Key) ->
gleam@result:all(gleam@list:map(get_as_list(Query, Key), fun parse_bool/1)).
-spec get_as_list_of_int(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
list(integer())} |
{error, binary()}.
get_as_list_of_int(Query, Key) ->
gleam@result:replace_error(
gleam@result:all(
gleam@list:map(get_as_list(Query, Key), fun gleam@int:parse/1)
),
<<"Couldn't parse all values"/utf8>>
).
-spec get_as_list_of_float(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
list(float())} |
{error, binary()}.
get_as_list_of_float(Query, Key) ->
gleam@result:replace_error(
gleam@result:all(
gleam@list:map(get_as_list(Query, Key), fun gleam@float:parse/1)
),
<<"Couldn't parse all values"/utf8>>
).
-spec maybe_get_as_list(gleam@map:map_(binary(), one_or_many()), binary()) -> {ok,
list(binary())} |
{error, binary()}.
maybe_get_as_list(Query, Key) ->
gleam@result:map(get(Query, Key), fun to_list/1).
-spec has_key(gleam@map:map_(binary(), one_or_many()), binary()) -> boolean().
has_key(Query, Key) ->
gleam@map:has_key(Query, Key).
-spec insert(gleam@map:map_(binary(), one_or_many()), binary(), one_or_many()) -> gleam@map:map_(binary(), one_or_many()).
insert(Query, Key, Value) ->
gleam@map:insert(Query, Key, Value).
-spec insert_one(gleam@map:map_(binary(), one_or_many()), binary(), binary()) -> gleam@map:map_(binary(), one_or_many()).
insert_one(Query, Key, Value) ->
insert(Query, Key, {one, Value}).
-spec insert_list(
gleam@map:map_(binary(), one_or_many()),
binary(),
list(binary())
) -> gleam@map:map_(binary(), one_or_many()).
insert_list(Query, Key, Values) ->
insert(Query, Key, {many, Values}).
-spec push(gleam@map:map_(binary(), one_or_many()), binary(), binary()) -> gleam@map:map_(binary(), one_or_many()).
push(Query, Key, Value) ->
gleam@map:update(Query, Key, fun(Res) -> case Res of
{ok, Current} ->
case Current of
{one, One} ->
{many, [One, Value]};
{many, Many} ->
{many, gleam@list:append(Many, [Value])}
end;
{error, _} ->
{many, [Value]}
end end).
-spec merge(
gleam@map:map_(binary(), one_or_many()),
gleam@map:map_(binary(), one_or_many())
) -> gleam@map:map_(binary(), one_or_many()).
merge(A, B) ->
gleam@map:merge(A, B).
-spec delete(gleam@map:map_(binary(), one_or_many()), binary()) -> gleam@map:map_(binary(), one_or_many()).
delete(Query, Key) ->
gleam@map:delete(Query, Key).
-spec parse_bool(binary()) -> {ok, boolean()} | {error, binary()}.
parse_bool(S) ->
case S of
<<"true"/utf8>> ->
{ok, true};
<<"false"/utf8>> ->
{ok, false};
_ ->
{error, gleam@string:append(<<"Invalid "/utf8>>, S)}
end.
-spec to_list(one_or_many()) -> list(binary()).
to_list(One_or_many) ->
case One_or_many of
{one, Value} ->
[Value];
{many, Values} ->
Values
end.