aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2022-01-09 19:15:21 +0000
committerLouis Pilfold <louis@lpil.uk>2022-01-09 19:15:21 +0000
commite5cfaa88421437ac9ddb77e6bea5298daec94e7f (patch)
tree0aa151681364d0be9003ab6c9b6bd4ad4bfb4249
parentfcdf32132d83c4b5d52d3d463bed2fc699649ab1 (diff)
downloadgleam_stdlib-e5cfaa88421437ac9ddb77e6bea5298daec94e7f.tar.gz
gleam_stdlib-e5cfaa88421437ac9ddb77e6bea5298daec94e7f.zip
Curry map
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/gleam/dynamic.gleam23
-rw-r--r--test/gleam/dynamic_test.gleam23
3 files changed, 44 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f4cd37..85bfc7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,8 @@
## v0.19.1 - 2022-01-09
- The `dynamic.dynamic` function now returns a result.
+- The `dynamic.map` function is now curried and requires the decoders for keys
+ and values to be supplied.
- The `dynamic.result`, `dynamic.optional`, `dynamic.field`, and `dynamic.list`
functions are now partially applied.
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index 1157014..496667d 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -841,8 +841,27 @@ pub fn tuple6(
/// Error(DecodeError(expected: "Map", found: "String", path: []))
/// ```
///
-pub fn map(from value: Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) {
- decode_map(value)
+pub fn map(
+ of key_type: Decoder(k),
+ to value_type: Decoder(v),
+) -> Decoder(Map(k, v)) {
+ fn(value) {
+ try map = decode_map(value)
+ try pairs =
+ map
+ |> map.to_list
+ |> list.try_map(fn(pair) {
+ let #(k, v) = pair
+ try k =
+ key_type(k)
+ |> map_errors(push_path(_, "keys"))
+ try v =
+ value_type(v)
+ |> map_errors(push_path(_, "values"))
+ Ok(#(k, v))
+ })
+ Ok(map.from_list(pairs))
+ }
}
if erlang {
diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam
index cbf58cf..cba6ff5 100644
--- a/test/gleam/dynamic_test.gleam
+++ b/test/gleam/dynamic_test.gleam
@@ -699,12 +699,31 @@ pub fn nested_tuples_test() {
pub fn map_test() {
map.new()
|> dynamic.from
- |> dynamic.map
+ |> dynamic.map(dynamic.string, dynamic.int)
|> should.equal(Ok(map.new()))
+ map.from_list([#("a", 1), #("b", 2)])
+ |> dynamic.from
+ |> dynamic.map(dynamic.string, dynamic.int)
+ |> should.equal(Ok(map.from_list([#("a", 1), #("b", 2)])))
+
+ map.from_list([#("a", 1), #("b", 2)])
+ |> dynamic.from
+ |> dynamic.map(dynamic.int, dynamic.int)
+ |> should.equal(Error([
+ DecodeError(expected: "Int", found: "String", path: ["keys"]),
+ ]))
+
+ map.from_list([#("a", 1), #("b", 2)])
+ |> dynamic.from
+ |> dynamic.map(dynamic.string, dynamic.string)
+ |> should.equal(Error([
+ DecodeError(expected: "String", found: "Int", path: ["values"]),
+ ]))
+
1
|> dynamic.from
- |> dynamic.map
+ |> dynamic.map(dynamic.string, dynamic.int)
|> should.equal(Error([DecodeError(expected: "Map", found: "Int", path: [])]))
}