diff options
author | Louis Pilfold <louis@lpil.uk> | 2022-01-09 17:27:02 +0000 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2022-01-09 17:27:02 +0000 |
commit | 63b6a706c30cc5ee4084ccb9bce40f2f8159cdbb (patch) | |
tree | 015ad2690ecaa7e8e447394c78c335a5b0ed7fdb | |
parent | 24e4b166bcf441e2cefaf50f04282a7a3e516283 (diff) | |
download | gleam_stdlib-63b6a706c30cc5ee4084ccb9bce40f2f8159cdbb.tar.gz gleam_stdlib-63b6a706c30cc5ee4084ccb9bce40f2f8159cdbb.zip |
decode3
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/dynamic.gleam | 34 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 27 |
3 files changed, 62 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a4e13de..ee8c6f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ - The decoder functions of the `dynamic` module now return multiple errors. - The `dynamic.any`, `dynamic.element` and `dynamic.tuple*` functions are now partially applied. -- The `dynamic` module gains the `decode2` function. +- The `dynamic` module gains the `decode2`, `decode3` functions. - The `int` module gains the `digits` and `undigits` functions. ## v0.18.1 - 2021-12-19 diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 4571b20..9aea340 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -910,6 +910,40 @@ pub fn decode2( } } +/// Decode 3 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode2(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Ok(MyRecord(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode2(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode3( + constructor: fn(t1, t2, t3) -> t, + decode1: Decoder(t1), + decode2: Decoder(t2), + decode3: Decoder(t3), +) -> Decoder(t) { + fn(value) { + case decode1(value), decode2(value), decode3(value) { + Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) + a, b, c -> + Error(list.flatten([all_errors(a), all_errors(b), all_errors(c)])) + } + } +} + fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { case result { Ok(_) -> [] diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index 1bfc255..c597b4e 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -811,3 +811,30 @@ pub fn decode2_test() { DecodeError(expected: "Float", found: "Int", path: ["1"]), ])) } + +type Three(a, b, c) { + Three(a, b, c) +} + +pub fn decode3_test() { + let decoder = + dynamic.decode3( + Three, + dynamic.element(0, dynamic.int), + dynamic.element(1, dynamic.float), + dynamic.element(2, dynamic.int), + ) + + #(1, 2.0, 3) + |> dynamic.from + |> decoder + |> should.equal(Ok(Three(1, 2.0, 3))) + + #(1.3, 2, 3) + |> dynamic.from + |> decoder + |> should.equal(Error([ + DecodeError(expected: "Int", found: "Float", path: ["0"]), + DecodeError(expected: "Float", found: "Int", path: ["1"]), + ])) +} |