diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-04 23:06:09 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-04 23:06:09 +0100 |
commit | 7a52f1356fe39475b7576ca5f105a10ae975e7ff (patch) | |
tree | 26aaef910ccba182d38474630bb904af732934f2 /src | |
parent | a54b1986daf44ebfd941849584175215306ad6d9 (diff) | |
download | gleam_stdlib-7a52f1356fe39475b7576ca5f105a10ae975e7ff.tar.gz gleam_stdlib-7a52f1356fe39475b7576ca5f105a10ae975e7ff.zip |
JS parse query
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/uri.gleam | 55 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 15 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 18 |
3 files changed, 56 insertions, 32 deletions
diff --git a/src/gleam/uri.gleam b/src/gleam/uri.gleam index e67837e..5482478 100644 --- a/src/gleam/uri.gleam +++ b/src/gleam/uri.gleam @@ -189,39 +189,34 @@ fn extra_required(list: List(a), remaining: Int) -> Int { } } -if erlang { - import gleam/io - - external fn erl_parse_query(String) -> Dynamic = - "uri_string" "dissect_query" +/// Parses an urlencoded query string into a list of key value pairs. +/// Returns an error for invalid encoding. +/// +/// The opposite operation is `uri.query_to_string`. +/// +/// ## Examples +/// +/// ``` +/// > parse_query("a=1&b=2") +/// +/// Ok([#("a", "1"), #("b", "2")]) +/// ``` +/// +pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { + do_parse_query(query) +} - /// Parses an urlencoded query string into a list of key value pairs. - /// Returns an error for invalid encoding. - /// - /// The opposite operation is `uri.query_to_string`. - /// - /// ## Examples - /// - /// ``` - /// > parse_query("a=1&b=2") - /// - /// Ok([#("a", "1"), #("b", "2")]) - /// ``` - /// - pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - let bool_value = fn(x) { result.map(dynamic.bool(x), fn(_) { "" }) } - let query_param = dynamic.typed_tuple2( - _, - dynamic.string, - dynamic.any(_, of: [dynamic.string, bool_value]), - ) +if erlang { + external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = + "gleam_stdlib" "parse_query" +} - query - |> erl_parse_query - |> dynamic.typed_list(of: query_param) - |> result.nil_error - } +if javascript { + external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = + "../gleam_stdlib.js" "parse_query" +} +if erlang { type Encoding { Utf8 } diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index 408853a..f8f6851 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -5,13 +5,13 @@ map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, decode_float/1, decode_thunk/1, decode_list/1, decode_optional/2, decode_field/2, decode_element/2, parse_int/1, parse_float/1, - less_than/2, string_pop_grapheme/1, string_starts_with/2, + less_than/2, string_pop_grapheme/1, string_starts_with/2, wrap_list/1, string_ends_with/2, string_pad/4, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, decode_tuple5/1, decode_tuple6/1, decode_map/1, bit_string_int_to_u32/1, bit_string_int_from_u32/1, decode_result/1, bit_string_slice/3, decode_bit_string/1, compile_regex/2, regex_check/2, regex_split/2, regex_scan/2, base_decode64/1, - wrap_list/1, bit_string_concat/1]). + parse_query/1, bit_string_concat/1]). should_equal(Actual, Expected) -> ?assertEqual(Expected, Actual), @@ -234,3 +234,14 @@ base_decode64(S) -> wrap_list(X) when is_list(X) -> X; wrap_list(X) -> [X]. + +parse_query(Query) -> + case uri_string:dissect_query(Query) of + {error, _, _} -> {error, nil}; + Pairs -> + Pairs1 = lists:map(fun + ({K, true}) -> {K, <<"">>}; + (Pair) -> Pair + end, Pairs), + {ok, Pairs1} + end. diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 360de75..082e661 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -352,3 +352,21 @@ export function map_get(map, key) { export function map_insert(key, value, map) { return map.insert(key, value); } + +function decode_query_component(string) { + return decodeURIComponent((string || "").replace("+", " ")); +} + +export function parse_query(query) { + try { + let pairs = []; + for (let section of query.split("&")) { + let [key, value] = section.split("="); + if (!key) continue; + pairs.push([decode_query_component(key), decode_query_component(value)]); + } + return new Ok(List.fromArray(pairs)); + } catch (error) { + return new Error(Nil); + } +} |