aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2022-01-09 17:51:28 +0000
committerLouis Pilfold <louis@lpil.uk>2022-01-09 17:51:28 +0000
commit3ea1726ae5040af3c67bd3dc8c1b6718c69ff67b (patch)
tree65b457a4f99887a5d74c5ac0e380ffbc4690f00d
parentd331545082e3cdaab501142facf56ac5a16ee745 (diff)
downloadgleam_stdlib-3ea1726ae5040af3c67bd3dc8c1b6718c69ff67b.tar.gz
gleam_stdlib-3ea1726ae5040af3c67bd3dc8c1b6718c69ff67b.zip
decode4
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/gleam/dynamic.gleam70
-rw-r--r--test/gleam/dynamic_test.gleam28
3 files changed, 90 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee8c6f3..28bbd3d 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`, `decode3` functions.
+- The `dynamic` module gains the `decode2`, `decode3`, `decode4` 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 9aea340..b920306 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -899,11 +899,11 @@ pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) {
///
pub fn decode2(
constructor: fn(t1, t2) -> t,
- decode1: Decoder(t1),
- decode2: Decoder(t2),
+ t1: Decoder(t1),
+ t2: Decoder(t2),
) -> Decoder(t) {
fn(value) {
- case decode1(value), decode2(value) {
+ case t1(value), t2(value) {
Ok(a), Ok(b) -> Ok(constructor(a, b))
a, b -> Error(list.flatten([all_errors(a), all_errors(b)]))
}
@@ -916,13 +916,13 @@ pub fn decode2(
///
/// ```gleam
/// > from(#(1, 2.0, "3"))
-/// > |> decode2(MyRecord, element(0, int), element(1, float), element(2, string))
+/// > |> decode3(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))
+/// > |> decode3(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"]),
@@ -931,12 +931,12 @@ pub fn decode2(
///
pub fn decode3(
constructor: fn(t1, t2, t3) -> t,
- decode1: Decoder(t1),
- decode2: Decoder(t2),
- decode3: Decoder(t3),
+ t1: Decoder(t1),
+ t2: Decoder(t2),
+ t3: Decoder(t3),
) -> Decoder(t) {
fn(value) {
- case decode1(value), decode2(value), decode3(value) {
+ case t1(value), t2(value), t3(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)]))
@@ -944,6 +944,58 @@ pub fn decode3(
}
}
+/// Decode 4 values from a `Dynamic` value.
+///
+/// ## Examples
+///
+/// ```gleam
+/// > from(#(1, 2.1, "3", "4"))
+/// > |> decode4(
+/// > MyRecord,
+/// > element(0, int),
+/// > element(1, float),
+/// > element(2, string),
+/// > element(3, string),
+/// > )
+/// Ok(MyRecord(1, 2.1, "3", "4"))
+/// ```
+///
+/// ```gleam
+/// > from(#("", "", "", ""))
+/// > |> decode4(
+/// > MyRecord,
+/// > element(0, int),
+/// > element(1, float),
+/// > element(2, string),
+/// > element(3, string),
+/// > )
+/// Error([
+/// DecodeError(expected: "Int", found: "String", path: ["0"]),
+/// DecodeError(expected: "Float", found: "String", path: ["1"]),
+/// ])
+/// ```
+///
+pub fn decode4(
+ constructor: fn(t1, t2, t3, t4) -> t,
+ t1: Decoder(t1),
+ t2: Decoder(t2),
+ t3: Decoder(t3),
+ t4: Decoder(t4),
+) -> Decoder(t) {
+ fn(x: Dynamic) {
+ case t1(x), t2(x), t3(x), t4(x) {
+ Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d))
+ a, b, c, d ->
+ Error(list.flatten([
+ all_errors(a),
+ all_errors(b),
+ all_errors(c),
+ all_errors(d),
+ ]))
+ }
+ }
+}
+
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 45704bc..245d894 100644
--- a/test/gleam/dynamic_test.gleam
+++ b/test/gleam/dynamic_test.gleam
@@ -838,3 +838,31 @@ pub fn decode3_test() {
DecodeError(expected: "String", found: "Float", path: ["1"]),
]))
}
+
+type Four(a, b, c, d) {
+ Four(a, b, c, d)
+}
+
+pub fn decode4_test() {
+ let decoder =
+ dynamic.decode4(
+ Four,
+ dynamic.element(0, dynamic.int),
+ dynamic.element(1, dynamic.string),
+ dynamic.element(2, dynamic.int),
+ dynamic.element(3, dynamic.int),
+ )
+
+ #(1, "2", 3, 4)
+ |> dynamic.from
+ |> decoder
+ |> should.equal(Ok(Four(1, "2", 3, 4)))
+
+ #(1.3, 2.1, 3, 4)
+ |> dynamic.from
+ |> decoder
+ |> should.equal(Error([
+ DecodeError(expected: "Int", found: "Float", path: ["0"]),
+ DecodeError(expected: "String", found: "Float", path: ["1"]),
+ ]))
+}