aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2020-07-07 12:06:07 +0100
committerLouis Pilfold <louis@lpil.uk>2020-07-07 12:06:07 +0100
commit28fdf1078ca67f224944bffebe46151ba4a9234a (patch)
tree1ce4df5b4827e96a89b5b575302dfbd30accdd32
parent508fd5b979c597e35313e1fea970356d9fbc6c96 (diff)
downloadgleam_stdlib-28fdf1078ca67f224944bffebe46151ba4a9234a.tar.gz
gleam_stdlib-28fdf1078ca67f224944bffebe46151ba4a9234a.zip
dynamic.any
-rw-r--r--CHANGELOG.md6
-rw-r--r--src/gleam/dynamic.gleam36
-rw-r--r--src/gleam/list.gleam2
-rw-r--r--src/gleam/uri.gleam24
4 files changed, 47 insertions, 21 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1db3cd2..f09670c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,13 @@
# Changelog
+## Unreleased
+
- Fix `uri.parse_query` to handle the case where query parameters are present
without a value.
+- The types for `list.find_map` have been relaxed.
+- The `dynamic.typed_list` argument label has changed from `containing` to
+ `of`.
+- The `dynamic` module gains the `any` function.
## v0.10.1 - 2020-07-01
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index 648ad0a..efd8dd5 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -166,18 +166,18 @@ pub external fn list(from: Dynamic) -> Result(List(Dynamic), String) =
///
/// ## Examples
///
-/// > typed_list(from(["a", "b", "c"]), containing: string)
+/// > typed_list(from(["a", "b", "c"]), of: string)
/// Ok(["a", "b", "c"])
///
-/// > typed_list(from([1, 2, 3]), containing: string)
+/// > typed_list(from([1, 2, 3]), of: string)
/// Error("Expected an Int, got a binary")
///
-/// > typed_list(from("ok"), containing: string)
+/// > typed_list(from("ok"), of: string)
/// Error("Expected a List, got a binary")
///
pub fn typed_list(
from dynamic: Dynamic,
- containing decoder_type: fn(Dynamic) -> Result(inner, String),
+ of decoder_type: fn(Dynamic) -> Result(inner, String),
) -> Result(List(inner), String) {
dynamic
|> list
@@ -289,3 +289,31 @@ pub fn typed_tuple2(
///
pub external fn map(from: Dynamic) -> Result(Map(Dynamic, Dynamic), String) =
"gleam_stdlib" "decode_map"
+
+/// Join multiple decoders into one. When run they will each be tried in turn
+/// until one succeeds, or they all fail.
+///
+/// ## Examples
+///
+/// > import gleam/result
+/// > let bool_or_string = any(_, of: [
+/// > string,
+/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) }
+/// > ])
+/// > bool_or_string(from("ok"))
+/// Ok("ok")
+///
+/// > bool_or_string(from(True))
+/// Ok("a bool")
+///
+/// > bool_or_string(from(1))
+/// Error("Unexpected value")
+///
+pub fn any(
+ from data: Dynamic,
+ of decoders: List(Decoder(t)),
+) -> Result(t, String) {
+ decoders
+ |> list_mod.find_map(fn(decoder) { decoder(data) })
+ |> result.map_error(fn(_) { "Unexpected value" })
+}
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index c7aee2f..b13575b 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -504,7 +504,7 @@ pub fn find(
///
pub fn find_map(
in haystack: List(a),
- with fun: fn(a) -> Result(b, Nil),
+ with fun: fn(a) -> Result(b, c),
) -> Result(b, Nil) {
case haystack {
[] -> Error(Nil)
diff --git a/src/gleam/uri.gleam b/src/gleam/uri.gleam
index 1c2447b..cf18952 100644
--- a/src/gleam/uri.gleam
+++ b/src/gleam/uri.gleam
@@ -79,24 +79,16 @@ external fn erl_parse_query(String) -> Dynamic =
/// The opposite operation is `uri.query_to_string`.
///
pub fn parse_query(query: String) -> Result(List(tuple(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]),
+ )
+
query
|> erl_parse_query
- |> dynamic.typed_list(
- dynamic.typed_tuple2(
- _,
- dynamic.string,
- fn(raw) {
- case dynamic.string(raw) {
- Ok(value) -> Ok(value)
- Error(_reason) -> case dynamic.bool(raw) {
- Ok(True) -> Ok("")
- // Note this error message will be niled at the end of this function.
- _ -> Error("expected a boolean or string, got neither")
- }
- }
- },
- ),
- )
+ |> dynamic.typed_list(of: query_param)
|> result.nil_error
}