diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-10 18:54:41 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-10 18:54:41 +0100 |
commit | 32ac4ec2523e7226cecbf73a1708cd36ea3b3eb1 (patch) | |
tree | dc3f238c77446f34c02e25f8dae269d14e41a6c9 | |
parent | 5c8f31c0d7d347bf733c91fb52037c4ffed9e87e (diff) | |
download | gleam_stdlib-32ac4ec2523e7226cecbf73a1708cd36ea3b3eb1.tar.gz gleam_stdlib-32ac4ec2523e7226cecbf73a1708cd36ea3b3eb1.zip |
JS list decoding
-rw-r--r-- | src/gleam/dynamic.gleam | 101 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 4 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 108 |
3 files changed, 116 insertions, 97 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index d82ae79..5dd0feb 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -215,24 +215,35 @@ if javascript { "../gleam_stdlib.js" "decode_bool" } +/// Checks to see whether a Dynamic value is a list, and return the list if it +/// is. +/// +/// If you wish to decode all the elements in the list use the `typed_list` +/// instead. +/// +/// ## Examples +/// +/// > list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// +/// > list(1) +/// Error(DecodeError(expected: "Int", found: "Int")) +/// +pub fn list(from value: Dynamic) -> Result(List(Dynamic), DecodeError) { + decode_list(value) +} + if erlang { - /// Checks to see whether a Dynamic value is a list, and return the list if it - /// is. - /// - /// If you wish to decode all the elements in the list use the `typed_list` - /// instead. - /// - /// ## Examples - /// - /// > list(from(["a", "b", "c"])) - /// Ok([from("a"), from("b"), from("c")]) - /// - /// > list(1) - /// Error(DecodeError(expected: "Int", found: "Int")) - /// - pub external fn list(from: Dynamic) -> Result(List(Dynamic), DecodeError) = + external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeError) = "gleam_stdlib" "decode_list" +} +if javascript { + external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeError) = + "../gleam_stdlib.js" "decode_list" +} + +if erlang { /// Checks to see whether a Dynamic value is a result, and return the result if /// it is. /// @@ -287,37 +298,39 @@ if erlang { |> result.map(Error) } } +} - /// Checks 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. - /// - /// If you do not wish to decode all the elements in the list use the `list` - /// function instead. - /// - /// ## Examples - /// - /// > typed_list(from(["a", "b", "c"]), of: string) - /// Ok(["a", "b", "c"]) - /// - /// > typed_list(from([1, 2, 3]), of: string) - /// Error(DecodeError(expected: "String", found: "Int")) - /// - /// > typed_list(from("ok"), of: string) - /// Error(DecodeError(expected: "List", found: "String")) - /// - pub fn typed_list( - from dynamic: Dynamic, - of decoder_type: fn(Dynamic) -> Result(inner, DecodeError), - ) -> Result(List(inner), DecodeError) { - dynamic - |> list - |> result.then(list.try_map(_, decoder_type)) - } +/// Checks 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. +/// +/// If you do not wish to decode all the elements in the list use the `list` +/// function instead. +/// +/// ## Examples +/// +/// > typed_list(from(["a", "b", "c"]), of: string) +/// Ok(["a", "b", "c"]) +/// +/// > typed_list(from([1, 2, 3]), of: string) +/// Error(DecodeError(expected: "String", found: "Int")) +/// +/// > typed_list(from("ok"), of: string) +/// Error(DecodeError(expected: "List", found: "String")) +/// +pub fn typed_list( + from dynamic: Dynamic, + of decoder_type: fn(Dynamic) -> Result(inner, DecodeError), +) -> Result(List(inner), DecodeError) { + dynamic + |> list + |> result.then(list.try_map(_, decoder_type)) +} +if erlang { /// Checks to see if a Dynamic value is a nullable version of a particular /// type, and return the Option if it is. /// diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 47801ce..500066d 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -527,3 +527,7 @@ export function tuple_get(data, index) { ? new Ok(data[index]) : new Error(Nil); } + +export function decode_list(data) { + return List.isList(data) ? new Ok(data) : decoder_error("List", data); +} diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index fd28f79..c93210b 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -160,49 +160,49 @@ pub fn bool_test() { |> should.equal(Error(DecodeError(expected: "Bool", found: "List"))) } -if erlang { - pub fn typed_list_test() { - [] - |> dynamic.from - |> dynamic.typed_list(dynamic.string) - |> should.equal(Ok([])) +pub fn typed_list_test() { + [] + |> dynamic.from + |> dynamic.typed_list(dynamic.string) + |> should.equal(Ok([])) - [] - |> dynamic.from - |> dynamic.typed_list(dynamic.int) - |> should.equal(Ok([])) + [] + |> dynamic.from + |> dynamic.typed_list(dynamic.int) + |> should.equal(Ok([])) - [1, 2, 3] - |> dynamic.from - |> dynamic.typed_list(dynamic.int) - |> should.equal(Ok([1, 2, 3])) + [1, 2, 3] + |> dynamic.from + |> dynamic.typed_list(dynamic.int) + |> should.equal(Ok([1, 2, 3])) - [[1], [2], [3]] - |> dynamic.from - |> dynamic.typed_list(dynamic.typed_list(_, dynamic.int)) - |> should.equal(Ok([[1], [2], [3]])) + [[1], [2], [3]] + |> dynamic.from + |> dynamic.typed_list(dynamic.typed_list(_, dynamic.int)) + |> should.equal(Ok([[1], [2], [3]])) - 1 - |> dynamic.from - |> dynamic.typed_list(dynamic.string) - |> should.be_error + 1 + |> dynamic.from + |> dynamic.typed_list(dynamic.string) + |> should.be_error - 1.0 - |> dynamic.from - |> dynamic.typed_list(dynamic.int) - |> should.be_error + 1.0 + |> dynamic.from + |> dynamic.typed_list(dynamic.int) + |> should.be_error - [""] - |> dynamic.from - |> dynamic.typed_list(dynamic.int) - |> should.be_error + [""] + |> dynamic.from + |> dynamic.typed_list(dynamic.int) + |> should.be_error - [dynamic.from(1), dynamic.from("not an int")] - |> dynamic.from - |> dynamic.typed_list(dynamic.int) - |> should.be_error - } + [dynamic.from(1), dynamic.from("not an int")] + |> dynamic.from + |> dynamic.typed_list(dynamic.int) + |> should.be_error +} +if erlang { pub fn optional_test() { 1 |> dynamic.from @@ -730,29 +730,31 @@ if erlang { |> dynamic.map |> should.equal(Error(DecodeError(expected: "Map", found: "Int"))) } +} - pub fn list_test() { - [] - |> dynamic.from - |> dynamic.list - |> should.equal(Ok([])) +pub fn list_test() { + [] + |> dynamic.from + |> dynamic.list + |> should.equal(Ok([])) - [1, 2] - |> dynamic.from - |> dynamic.list - |> should.equal(Ok([dynamic.from(1), dynamic.from(2)])) + [1, 2] + |> dynamic.from + |> dynamic.list + |> should.equal(Ok([dynamic.from(1), dynamic.from(2)])) - [dynamic.from(1), dynamic.from(2.0)] - |> dynamic.from - |> dynamic.list - |> should.equal(Ok([dynamic.from(1), dynamic.from(2.0)])) + [dynamic.from(1), dynamic.from(2.0)] + |> dynamic.from + |> dynamic.list + |> should.equal(Ok([dynamic.from(1), dynamic.from(2.0)])) - 1 - |> dynamic.from - |> dynamic.list - |> should.equal(Error(DecodeError(expected: "List", found: "Int"))) - } + 1 + |> dynamic.from + |> dynamic.list + |> should.equal(Error(DecodeError(expected: "List", found: "Int"))) +} +if erlang { pub fn result_test() { Ok(1) |> dynamic.from |