-module(qs). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/qs.gleam"). -export([default_config/0, with_fail_on_invalid/2, parse_key_value/1, empty/0, split_and_parse/2, parse/2, default_parse/1, add_question_mark/1, encode/1, default_serialize/1, decode/1, get/2, has_key/2, insert/3, merge/2, delete/2]). -export_type([config/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. -type config() :: {config, boolean()}. -file("src/qs.gleam", 21). -spec default_config() -> config(). default_config() -> {config, false}. -file("src/qs.gleam", 25). -spec with_fail_on_invalid(config(), boolean()) -> config(). with_fail_on_invalid(_, Value) -> {config, Value}. -file("src/qs.gleam", 34). ?DOC(false). -spec parse_key_value(binary()) -> {ok, {binary(), binary()}} | {error, binary()}. parse_key_value(Segment) -> Decoded = begin _pipe = Segment, _pipe@1 = gleam@uri:percent_decode(_pipe), gleam@result:unwrap(_pipe@1, Segment) end, Split_result = gleam@string:split_once(Decoded, <<"="/utf8>>), Unabled_to_parse = <<"Unable to parse "/utf8, Segment/binary>>, case Split_result of {ok, {Key, Value}} -> case Value of <<""/utf8>> -> {error, Unabled_to_parse}; _ -> {ok, {Key, Value}} end; {error, _} -> {error, Unabled_to_parse} end. -file("src/qs.gleam", 100). -spec add_key_value( gleam@dict:dict(binary(), list(binary())), {binary(), binary()} ) -> gleam@dict:dict(binary(), list(binary())). add_key_value(Query, Key_value) -> {Key, Value} = Key_value, Updater = fun(Res) -> case Res of {some, Existing} -> lists:append(Existing, [Value]); none -> [Value] end end, gleam@dict:upsert(Query, Key, Updater). -file("src/qs.gleam", 157). ?DOC(" Make an empty Query\n"). -spec empty() -> gleam@dict:dict(binary(), any()). empty() -> gleam@dict:new(). -file("src/qs.gleam", 84). ?DOC(false). -spec split_and_parse(binary(), boolean()) -> {ok, list({binary(), binary()})} | {error, binary()}. split_and_parse(Query, Fail_on_invalid) -> Results = begin _pipe = Query, _pipe@1 = gleam@string:replace(_pipe, <<"?"/utf8>>, <<""/utf8>>), _pipe@2 = gleam@string:split(_pipe@1, <<"&"/utf8>>), gleam@list:map(_pipe@2, fun parse_key_value/1) end, case Fail_on_invalid of true -> _pipe@3 = Results, gleam@result:all(_pipe@3); false -> _pipe@4 = Results, _pipe@5 = gleam@result:values(_pipe@4), {ok, _pipe@5} end. -file("src/qs.gleam", 76). -spec parse(binary(), config()) -> {ok, gleam@dict:dict(binary(), list(binary()))} | {error, binary()}. parse(Input, Config) -> gleam@result:then( split_and_parse(Input, erlang:element(2, Config)), fun(Key_values) -> _pipe = gleam@list:fold(Key_values, empty(), fun add_key_value/2), {ok, _pipe} end ). -file("src/qs.gleam", 72). ?DOC( " Parse a query string.\n" " Values that cannot be parsed are ignored.\n" "\n" " ## Example\n" "\n" " ```\n" " \"?color=red&tags=large&tags=wool\"\n" " |> qs.default_parse\n" "\n" " ==\n" "\n" " Ok(\n" " dict.from_list(\n" " [ #(\"color\", [\"red\"]), #(\"tags\", [\"large\", \"wool\"]) ]\n" " )\n" " )\n" " ```\n" ). -spec default_parse(binary()) -> {ok, gleam@dict:dict(binary(), list(binary()))} | {error, binary()}. default_parse(Qs) -> parse(Qs, default_config()). -file("src/qs.gleam", 139). ?DOC(false). -spec add_question_mark(binary()) -> binary(). add_question_mark(Query) -> case Query of <<""/utf8>> -> <<""/utf8>>; _ -> <<"?"/utf8, Query/binary>> end. -file("src/qs.gleam", 152). ?DOC(false). -spec encode(binary()) -> binary(). encode(Val) -> gleam@uri:percent_encode(Val). -file("src/qs.gleam", 133). -spec serialize_key_value({binary(), list(binary())}) -> list(binary()). serialize_key_value(Key_value) -> {Key, Values} = Key_value, gleam@list:map( Values, fun(Value) -> <<<<(encode(Key))/binary, "="/utf8>>/binary, (encode(Value))/binary>> end ). -file("src/qs.gleam", 125). ?DOC( " Serialize a query\n" "\n" " ## Example\n" "\n" " ```\n" " [ #(\"color\", [\"red\"]), #(\"tag\", [\"large\", \"wool\"]) ]\n" " |> qs.default_serialize\n" "\n" " ==\n" "\n" " \"?color=red&tag=large&tag=wool\"\n" " ```\n" ). -spec default_serialize(gleam@dict:dict(binary(), list(binary()))) -> binary(). default_serialize(Query) -> _pipe = Query, _pipe@1 = maps:to_list(_pipe), _pipe@2 = gleam@list:flat_map(_pipe@1, fun serialize_key_value/1), _pipe@3 = gleam@string:join(_pipe@2, <<"&"/utf8>>), add_question_mark(_pipe@3). -file("src/qs.gleam", 147). ?DOC(false). -spec decode(binary()) -> {ok, binary()} | {error, nil}. decode(Val) -> gleam@uri:percent_decode(Val). -file("src/qs.gleam", 162). ?DOC(" Get values from the query\n"). -spec get(gleam@dict:dict(binary(), FPF), binary()) -> {ok, FPF} | {error, binary()}. get(Query, Key) -> Error = <<"Invalid key "/utf8, Key/binary>>, _pipe = gleam@dict:get(Query, Key), gleam@result:replace_error(_pipe, Error). -file("src/qs.gleam", 170). ?DOC(" Tell if the query has the given key\n"). -spec has_key(gleam@dict:dict(binary(), any()), binary()) -> boolean(). has_key(Query, Key) -> gleam@dict:has_key(Query, Key). -file("src/qs.gleam", 176). ?DOC( " Insert a value in the query\n" " Replaces existing values\n" ). -spec insert(gleam@dict:dict(binary(), FPL), binary(), FPL) -> gleam@dict:dict(binary(), FPL). insert(Query, Key, Value) -> gleam@dict:insert(Query, Key, Value). -file("src/qs.gleam", 182). ?DOC( " Merge two Querys.\n" " Second query takes precedence.\n" ). -spec merge(gleam@dict:dict(binary(), FPO), gleam@dict:dict(binary(), FPO)) -> gleam@dict:dict(binary(), FPO). merge(A, B) -> gleam@dict:merge(A, B). -file("src/qs.gleam", 187). ?DOC(" Delete a key from the query\n"). -spec delete(gleam@dict:dict(binary(), FPS), binary()) -> gleam@dict:dict(binary(), FPS). delete(Query, Key) -> gleam@dict:delete(Query, Key).