aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevuez <helloevuez@gmail.com>2021-02-23 14:12:57 +0100
committerGitHub <noreply@github.com>2021-02-23 13:12:57 +0000
commit3464cbb286b4f17cbfd4239aa5ddcfd1bf6a871c (patch)
treef57a3965e03c0843b5899d29a33223c22a7b883b
parent9424ebf22a18a46b871a5236457d4b08aca6b7cf (diff)
downloadgleam_stdlib-3464cbb286b4f17cbfd4239aa5ddcfd1bf6a871c.tar.gz
gleam_stdlib-3464cbb286b4f17cbfd4239aa5ddcfd1bf6a871c.zip
Add dynamic.tuple{3,4,5,6} (#165)
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/gleam/dynamic.gleam230
-rw-r--r--src/gleam_stdlib.erl15
-rw-r--r--test/gleam/dynamic_test.gleam302
4 files changed, 547 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 48f759f..c8a6117 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
## Unreleased
+- The `dynamic` module gains the `tuple3`, `tuple4`, `tuple5`, `tuple6` functions and
+ their typed equivalents `typed_tuple3`, `typed_tuple4`, `typed_tuple5`, `typed_tuple6`.
- The `list` modules gains the `drop_while` and `take_while` functions.
## v0.14.0 - 2021-02-18
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index 55462b2..aa1ff5d 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -328,7 +328,7 @@ pub external fn element(from: Dynamic, position: Int) -> Result(Dynamic, String)
/// > tuple2(from(tuple(1, 2)))
/// Ok(tuple(from(1), from(2)))
///
-/// > tuple2(from(tuple(1, 2)))
+/// > tuple2(from(tuple(1, 2, 3)))
/// Error("Expected a 2 element tuple")
///
/// > tuple2(from(""))
@@ -368,6 +368,234 @@ pub fn typed_tuple2(
Ok(tuple(a, b))
}
+/// Checks to see if the Dynamic value is a 3 element tuple.
+///
+/// If you do not wish to decode all the elements in the tuple use the
+/// `typed_tuple3` function instead.
+///
+/// ## Examples
+///
+/// > tuple3(from(tuple(1, 2, 3)))
+/// Ok(tuple(from(1), from(2), from(3)))
+///
+/// > tuple3(from(tuple(1, 2)))
+/// Error("Expected a 3 element tuple")
+///
+/// > tuple3(from(""))
+/// Error("Expected a tuple, got a binary")
+///
+pub external fn tuple3(
+ from: Dynamic,
+) -> Result(tuple(Dynamic, Dynamic, Dynamic), String) =
+ "gleam_stdlib" "decode_tuple3"
+
+/// Checks to see if the Dynamic value is a 3 element tuple containing two
+/// specifically typed elements.
+///
+/// If you wish to decode all the elements in the list use the `typed_tuple3`
+/// instead.
+///
+/// ## Examples
+///
+/// > typed_tuple3(from(tuple(1, 2, 3)), int, int, int)
+/// Ok(tuple(1, 2, 3))
+///
+/// > typed_tuple3(from(tuple(1, 2.0, "3")), int, float, string)
+/// Ok(tuple(1, 2.0, "3"))
+///
+/// > typed_tuple3(from(tuple(1, 2)), int, float, string)
+/// Error("Expected a 3 element tuple, got a 2 element tuple")
+///
+/// > typed_tuple3(from(""), int, float, string)
+/// Error("Expected a tuple, got a binary")
+///
+pub fn typed_tuple3(
+ from tup: Dynamic,
+ first decode_first: Decoder(a),
+ second decode_second: Decoder(b),
+ third decode_third: Decoder(c),
+) -> Result(tuple(a, b, c), String) {
+ try tuple(first, second, third) = tuple3(tup)
+ try a = decode_first(first)
+ try b = decode_second(second)
+ try c = decode_third(third)
+ Ok(tuple(a, b, c))
+}
+
+/// Checks to see if the Dynamic value is a 4 element tuple.
+///
+/// If you do not wish to decode all the elements in the tuple use the
+/// `typed_tuple4` function instead.
+///
+/// ## Examples
+///
+/// > tuple4(from(tuple(1, 2, 3, 4)))
+/// Ok(tuple(from(1), from(2), from(3), from(4)))
+///
+/// > tuple4(from(tuple(1, 2)))
+/// Error("Expected a 4 element tuple")
+///
+/// > tuple4(from(""))
+/// Error("Expected a tuple, got a binary")
+///
+pub external fn tuple4(
+ from: Dynamic,
+) -> Result(tuple(Dynamic, Dynamic, Dynamic, Dynamic), String) =
+ "gleam_stdlib" "decode_tuple4"
+
+/// Checks to see if the Dynamic value is a 4 element tuple containing two
+/// specifically typed elements.
+///
+/// If you wish to decode all the elements in the list use the `typed_tuple4`
+/// instead.
+///
+/// ## Examples
+///
+/// > typed_tuple4(from(tuple(1, 2, 3, 4)), int, int, int, int)
+/// Ok(tuple(1, 2, 3, 4))
+///
+/// > typed_tuple4(from(tuple(1, 2.0, "3", 4)), int, float, string, int)
+/// Ok(tuple(1, 2.0, "3", 4))
+///
+/// > typed_tuple4(from(tuple(1, 2)), int, float, string, int)
+/// Error("Expected a 4 element tuple, got a 2 element tuple")
+///
+/// > typed_tuple4(from(""), int, float, string, int)
+/// Error("Expected a tuple, got a binary")
+///
+pub fn typed_tuple4(
+ from tup: Dynamic,
+ first decode_first: Decoder(a),
+ second decode_second: Decoder(b),
+ third decode_third: Decoder(c),
+ fourth decode_fourth: Decoder(d),
+) -> Result(tuple(a, b, c, d), String) {
+ try tuple(first, second, third, fourth) = tuple4(tup)
+ try a = decode_first(first)
+ try b = decode_second(second)
+ try c = decode_third(third)
+ try d = decode_fourth(fourth)
+ Ok(tuple(a, b, c, d))
+}
+
+/// Checks to see if the Dynamic value is a 5 element tuple.
+///
+/// If you do not wish to decode all the elements in the tuple use the
+/// `typed_tuple5` function instead.
+///
+/// ## Examples
+///
+/// > tuple5(from(tuple(1, 2, 3, 4, 5)))
+/// Ok(tuple(from(1), from(2), from(3), from(4), from(5)))
+///
+/// > tuple5(from(tuple(1, 2)))
+/// Error("Expected a 5 element tuple")
+///
+/// > tuple5(from(""))
+/// Error("Expected a tuple, got a binary")
+///
+pub external fn tuple5(
+ from: Dynamic,
+) -> Result(tuple(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), String) =
+ "gleam_stdlib" "decode_tuple5"
+
+/// Checks to see if the Dynamic value is a 5 element tuple containing two
+/// specifically typed elements.
+///
+/// If you wish to decode all the elements in the list use the `typed_tuple5`
+/// instead.
+///
+/// ## Examples
+///
+/// > typed_tuple5(from(tuple(1, 2, 3, 4, 5)), int, int, int, int, int)
+/// Ok(tuple(1, 2, 3, 4, 5))
+///
+/// > typed_tuple5(from(tuple(1, 2.0, "3", 4, 5)), int, float, string, int, int)
+/// Ok(tuple(1, 2.0, "3", 4, 5))
+///
+/// > typed_tuple5(from(tuple(1, 2)), int, float, string, int, int)
+/// Error("Expected a 5 element tuple, got a 2 element tuple")
+///
+/// > typed_tuple5(from(""), int, float, string, int, int)
+/// Error("Expected a tuple, got a binary")
+///
+pub fn typed_tuple5(
+ from tup: Dynamic,
+ first decode_first: Decoder(a),
+ second decode_second: Decoder(b),
+ third decode_third: Decoder(c),
+ fourth decode_fourth: Decoder(d),
+ fifth decode_fifth: Decoder(e),
+) -> Result(tuple(a, b, c, d, e), String) {
+ try tuple(first, second, third, fourth, fifth) = tuple5(tup)
+ try a = decode_first(first)
+ try b = decode_second(second)
+ try c = decode_third(third)
+ try d = decode_fourth(fourth)
+ try e = decode_fifth(fifth)
+ Ok(tuple(a, b, c, d, e))
+}
+
+/// Checks to see if the Dynamic value is a 6 element tuple.
+///
+/// If you do not wish to decode all the elements in the tuple use the
+/// `typed_tuple6` function instead.
+///
+/// ## Examples
+///
+/// > tuple6(from(tuple(1, 2, 3, 4, 5, 6)))
+/// Ok(tuple(from(1), from(2), from(3), from(4), from(5), from(6)))
+///
+/// > tuple6(from(tuple(1, 2)))
+/// Error("Expected a 6 element tuple")
+///
+/// > tuple6(from(""))
+/// Error("Expected a tuple, got a binary")
+///
+pub external fn tuple6(
+ from: Dynamic,
+) -> Result(tuple(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), String) =
+ "gleam_stdlib" "decode_tuple6"
+
+/// Checks to see if the Dynamic value is a 6 element tuple containing two
+/// specifically typed elements.
+///
+/// If you wish to decode all the elements in the list use the `typed_tuple6`
+/// instead.
+///
+/// ## Examples
+///
+/// > typed_tuple6(from(tuple(1, 2, 3, 4, 5, 6)), int, int, int, int, int, int)
+/// Ok(tuple(1, 2, 3, 4, 5, 6))
+///
+/// > typed_tuple6(from(tuple(1, 2.0, "3", 4, 5, 6)), int, float, string, int, int)
+/// Ok(tuple(1, 2.0, "3", 4, 5, 6))
+///
+/// > typed_tuple6(from(tuple(1, 2)), int, float, string, int, int, int)
+/// Error("Expected a 6 element tuple, got a 2 element tuple")
+///
+/// > typed_tuple6(from(""), int, float, string, int, int, int)
+/// Error("Expected a tuple, got a binary")
+///
+pub fn typed_tuple6(
+ from tup: Dynamic,
+ first decode_first: Decoder(a),
+ second decode_second: Decoder(b),
+ third decode_third: Decoder(c),
+ fourth decode_fourth: Decoder(d),
+ fifth decode_fifth: Decoder(e),
+ sixth decode_sixth: Decoder(f),
+) -> Result(tuple(a, b, c, d, e, f), String) {
+ try tuple(first, second, third, fourth, fifth, sixth) = tuple6(tup)
+ try a = decode_first(first)
+ try b = decode_second(second)
+ try c = decode_third(third)
+ try d = decode_fourth(fourth)
+ try e = decode_fifth(fifth)
+ try f = decode_sixth(sixth)
+ Ok(tuple(a, b, c, d, e, f))
+}
+
/// Checks to see if the Dynamic value is map.
///
/// ## Examples
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index e8cc7e4..10d3752 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -8,7 +8,8 @@
decode_thunk/1, decode_atom/1, decode_list/1, decode_field/2,
decode_element/2, parse_int/1, parse_float/1, compare_strings/2,
string_pop_grapheme/1, string_starts_with/2, string_ends_with/2,
- string_pad/4, decode_tuple2/1, decode_map/1, bit_string_int_to_u32/1,
+ string_pad/4, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1,
+ decode_tuple5/1, decode_tuple6/1, decode_map/1, bit_string_int_to_u32/1,
bit_string_int_from_u32/1, bit_string_append/2, bit_string_part_/3,
decode_bit_string/1, compile_regex/2, regex_match/2, regex_split/2,
regex_scan/2, base_decode64/1, wrap_list/1, rescue/1, get_line/1]).
@@ -56,6 +57,18 @@ classify(_) -> "some other type".
decode_tuple2({_, _} = T) -> {ok, T};
decode_tuple2(Data) -> decode_error_msg("a 2 element tuple", Data).
+decode_tuple3({_, _, _} = T) -> {ok, T};
+decode_tuple3(Data) -> decode_error_msg("a 3 element tuple", Data).
+
+decode_tuple4({_, _, _, _} = T) -> {ok, T};
+decode_tuple4(Data) -> decode_error_msg("a 4 element tuple", Data).
+
+decode_tuple5({_, _, _, _, _} = T) -> {ok, T};
+decode_tuple5(Data) -> decode_error_msg("a 5 element tuple", Data).
+
+decode_tuple6({_, _, _, _, _, _} = T) -> {ok, T};
+decode_tuple6(Data) -> decode_error_msg("a 6 element tuple", Data).
+
decode_map(Data) when is_map(Data) -> {ok, Data};
decode_map(Data) -> decode_error_msg("a map", Data).
diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam
index d8b3be4..50c5ac4 100644
--- a/test/gleam/dynamic_test.gleam
+++ b/test/gleam/dynamic_test.gleam
@@ -356,6 +356,308 @@ pub fn typed_tuple2_test() {
|> should.equal(Error("Expected a 2 element tuple, got an int"))
}
+pub fn tuple3_test() {
+ tuple(1, 2, 3)
+ |> dynamic.from
+ |> dynamic.tuple3
+ |> should.equal(Ok(tuple(dynamic.from(1), dynamic.from(2), dynamic.from(3))))
+
+ tuple(1, "", 3.0)
+ |> dynamic.from
+ |> dynamic.tuple3
+ |> should.equal(Ok(tuple(dynamic.from(1), dynamic.from(""), dynamic.from(3.0))))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.tuple3
+ |> should.equal(Error("Expected a 3 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.tuple3
+ |> should.equal(Error("Expected a 3 element tuple, got an int"))
+}
+
+pub fn typed_tuple3_test() {
+ tuple(1, 2, 3)
+ |> dynamic.from
+ |> dynamic.typed_tuple3(dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Ok(tuple(1, 2, 3)))
+
+ tuple(1, "", 3.0)
+ |> dynamic.from
+ |> dynamic.typed_tuple3(dynamic.int, dynamic.string, dynamic.float)
+ |> should.equal(Ok(tuple(1, "", 3.0)))
+
+ tuple(1, 2, "")
+ |> dynamic.from
+ |> dynamic.typed_tuple3(dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected an int, got a binary"))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.typed_tuple3(dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected a 3 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.typed_tuple3(dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected a 3 element tuple, got an int"))
+}
+
+pub fn tuple4_test() {
+ tuple(1, 2, 3, 4)
+ |> dynamic.from
+ |> dynamic.tuple4
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(2),
+ dynamic.from(3),
+ dynamic.from(4),
+ )))
+
+ tuple(1, "", 3.0, 4)
+ |> dynamic.from
+ |> dynamic.tuple4
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(""),
+ dynamic.from(3.0),
+ dynamic.from(4),
+ )))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.tuple4
+ |> should.equal(Error("Expected a 4 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.tuple4
+ |> should.equal(Error("Expected a 4 element tuple, got an int"))
+}
+
+pub fn typed_tuple4_test() {
+ tuple(1, 2, 3, 4)
+ |> dynamic.from
+ |> dynamic.typed_tuple4(dynamic.int, dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Ok(tuple(1, 2, 3, 4)))
+
+ tuple(1, "", 3.0, 4)
+ |> dynamic.from
+ |> dynamic.typed_tuple4(
+ dynamic.int,
+ dynamic.string,
+ dynamic.float,
+ dynamic.int,
+ )
+ |> should.equal(Ok(tuple(1, "", 3.0, 4)))
+
+ tuple(1, 2, 3, "")
+ |> dynamic.from
+ |> dynamic.typed_tuple4(dynamic.int, dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected an int, got a binary"))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.typed_tuple4(dynamic.int, dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected a 4 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.typed_tuple4(dynamic.int, dynamic.int, dynamic.int, dynamic.int)
+ |> should.equal(Error("Expected a 4 element tuple, got an int"))
+}
+
+pub fn tuple5_test() {
+ tuple(1, 2, 3, 4, 5)
+ |> dynamic.from
+ |> dynamic.tuple5
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(2),
+ dynamic.from(3),
+ dynamic.from(4),
+ dynamic.from(5),
+ )))
+
+ tuple(1, "", 3.0, 4, 5)
+ |> dynamic.from
+ |> dynamic.tuple5
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(""),
+ dynamic.from(3.0),
+ dynamic.from(4),
+ dynamic.from(5),
+ )))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.tuple5
+ |> should.equal(Error("Expected a 5 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.tuple5
+ |> should.equal(Error("Expected a 5 element tuple, got an int"))
+}
+
+pub fn typed_tuple5_test() {
+ tuple(1, 2, 3, 4, 5)
+ |> dynamic.from
+ |> dynamic.typed_tuple5(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Ok(tuple(1, 2, 3, 4, 5)))
+
+ tuple(1, "", 3.0, 4, 5)
+ |> dynamic.from
+ |> dynamic.typed_tuple5(
+ dynamic.int,
+ dynamic.string,
+ dynamic.float,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Ok(tuple(1, "", 3.0, 4, 5)))
+
+ tuple(1, 2, 3, 4, "")
+ |> dynamic.from
+ |> dynamic.typed_tuple5(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected an int, got a binary"))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.typed_tuple5(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected a 5 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.typed_tuple5(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected a 5 element tuple, got an int"))
+}
+
+pub fn tuple6_test() {
+ tuple(1, 2, 3, 4, 5, 6)
+ |> dynamic.from
+ |> dynamic.tuple6
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(2),
+ dynamic.from(3),
+ dynamic.from(4),
+ dynamic.from(5),
+ dynamic.from(6),
+ )))
+
+ tuple(1, "", 3.0, 4, 5, 6)
+ |> dynamic.from
+ |> dynamic.tuple6
+ |> should.equal(Ok(tuple(
+ dynamic.from(1),
+ dynamic.from(""),
+ dynamic.from(3.0),
+ dynamic.from(4),
+ dynamic.from(5),
+ dynamic.from(6),
+ )))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.tuple6
+ |> should.equal(Error("Expected a 6 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.tuple6
+ |> should.equal(Error("Expected a 6 element tuple, got an int"))
+}
+
+pub fn typed_tuple6_test() {
+ tuple(1, 2, 3, 4, 5, 6)
+ |> dynamic.from
+ |> dynamic.typed_tuple6(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Ok(tuple(1, 2, 3, 4, 5, 6)))
+
+ tuple(1, "", 3.0, 4, 5, 6)
+ |> dynamic.from
+ |> dynamic.typed_tuple6(
+ dynamic.int,
+ dynamic.string,
+ dynamic.float,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Ok(tuple(1, "", 3.0, 4, 5, 6)))
+
+ tuple(1, 2, 3, 4, 5, "")
+ |> dynamic.from
+ |> dynamic.typed_tuple6(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected an int, got a binary"))
+
+ tuple(1, 2)
+ |> dynamic.from
+ |> dynamic.typed_tuple6(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected a 6 element tuple, got a 2 element tuple"))
+
+ 1
+ |> dynamic.from
+ |> dynamic.typed_tuple6(
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ dynamic.int,
+ )
+ |> should.equal(Error("Expected a 6 element tuple, got an int"))
+}
+
pub fn map_test() {
map.new()
|> dynamic.from