diff options
-rw-r--r-- | src/gleam/dynamic.gleam | 23 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 22 |
2 files changed, 41 insertions, 4 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 89826ec..3778a47 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -113,14 +113,29 @@ pub external fn bool(from: Dynamic) -> Result(Bool, String) = pub external fn thunk(from: Dynamic) -> Result(fn() -> Dynamic, String) = "gleam_stdlib" "decode_thunk" -external fn list_dynamic(from: Dynamic) -> Result(List(Dynamic), String) = - "gleam_stdlib" "decode_list" - /// Check to see whether a Dynamic value is a list, and return the list if it /// is. /// /// ## Examples /// +/// > opaque_list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// +/// > opaque_list(1) +/// Error("Expected an Int, got a binary") +/// +pub external fn opaque_list(from: Dynamic) -> Result(List(Dynamic), String) = + "gleam_stdlib" "decode_list" + +/// Check to see whether a Dynamic value is a list of a particular type, and +/// return the list if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// ## Examples +/// /// > list(from(["a", "b", "c"]), string) /// Ok(["a", "b", "c"]) /// @@ -135,7 +150,7 @@ pub fn list( containing decoder_type: fn(Dynamic) -> Result(inner, String), ) -> Result(List(inner), String) { dynamic - |> list_dynamic + |> opaque_list |> result.then(list_mod.traverse(_, decoder_type)) } diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index 5b5a88c..410ae0e 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -316,3 +316,25 @@ pub fn map_test() { |> dynamic.map |> should.equal(Error("Expected a map, got an int")) } + +pub fn opaque_list_test() { + [] + |> dynamic.from + |> dynamic.opaque_list + |> should.equal(Ok([])) + + [1, 2] + |> dynamic.from + |> dynamic.opaque_list + |> should.equal(Ok([dynamic.from(1), dynamic.from(2)])) + + [dynamic.from(1), dynamic.from(2.0)] + |> dynamic.from + |> dynamic.opaque_list + |> should.equal(Ok([dynamic.from(1), dynamic.from(2.0)])) + + 1 + |> dynamic.from + |> dynamic.opaque_list + |> should.equal(Error("Expected a list, got an int")) +} |