aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/dynamic.gleam27
-rw-r--r--test/gleam/dynamic_test.gleam20
2 files changed, 47 insertions, 0 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index f84db90..8cdebcd 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -987,6 +987,33 @@ pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) {
}
}
+/// Decode 1 values from a `Dynamic` value.
+///
+/// ## Examples
+///
+/// ```gleam
+/// > from(#(1, 2.0, "3"))
+/// > |> decode1(MyRecord, element(0, int))
+/// Ok(MyRecord(1))
+/// ```
+///
+/// ```gleam
+/// > from(#("", "", ""))
+/// > |> decode1(MyRecord, element(0, int))
+/// Error([
+/// DecodeError(expected: "Int", found: "String", path: ["0"]),
+/// ])
+/// ```
+///
+pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) {
+ fn(value) {
+ case t1(value) {
+ Ok(a) -> Ok(constructor(a))
+ a -> Error(all_errors(a))
+ }
+ }
+}
+
/// Decode 2 values from a `Dynamic` value.
///
/// ## Examples
diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam
index 9d1aeba..0caf8c5 100644
--- a/test/gleam/dynamic_test.gleam
+++ b/test/gleam/dynamic_test.gleam
@@ -838,6 +838,26 @@ pub fn any_test() {
|> should.equal(Error([DecodeError("another type", "String", path: [])]))
}
+type One(a) {
+ One(a)
+}
+
+pub fn decode1_test() {
+ let decoder = dynamic.decode1(One, dynamic.element(0, dynamic.int))
+
+ #(1)
+ |> dynamic.from
+ |> decoder
+ |> should.equal(Ok(One(1)))
+
+ #(1.3)
+ |> dynamic.from
+ |> decoder
+ |> should.equal(Error([
+ DecodeError(expected: "Int", found: "Float", path: ["0"]),
+ ]))
+}
+
type Two(a, b) {
Two(a, b)
}