aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRJ Dellecese <rjdellecese@gmail.com>2019-12-18 22:04:16 -0500
committerLouis Pilfold <louis@lpil.uk>2019-12-19 10:35:55 +0000
commitdd7dd9b1df1c77a62c49ca6e2620f6757b5b0734 (patch)
treee519bb3fd5573c0bd067d1f7c62c407fee8a37bd
parent2be45a710cb7332cf3c9a16d251c97561f88109c (diff)
downloadgleam_stdlib-dd7dd9b1df1c77a62c49ca6e2620f6757b5b0734.tar.gz
gleam_stdlib-dd7dd9b1df1c77a62c49ca6e2620f6757b5b0734.zip
Add dynamic.element for decoding tuples
-rw-r--r--gen/src/gleam@dynamic.erl5
-rw-r--r--gen/test/gleam@dynamic_test.erl28
-rw-r--r--src/gleam/dynamic.gleam3
-rw-r--r--src/gleam_stdlib.erl14
-rw-r--r--test/gleam/dynamic_test.gleam37
5 files changed, 84 insertions, 3 deletions
diff --git a/gen/src/gleam@dynamic.erl b/gen/src/gleam@dynamic.erl
index e20db87..09a442b 100644
--- a/gen/src/gleam@dynamic.erl
+++ b/gen/src/gleam@dynamic.erl
@@ -1,7 +1,7 @@
-module(gleam@dynamic).
-compile(no_auto_import).
--export([from/1, unsafe_coerce/1, string/1, int/1, float/1, atom/1, bool/1, thunk/1, list/2, field/2]).
+-export([from/1, unsafe_coerce/1, string/1, int/1, float/1, atom/1, bool/1, thunk/1, list/2, field/2, element/2]).
from(A) ->
gleam_stdlib:identity(A).
@@ -38,3 +38,6 @@ list(Dynamic, DecoderType) ->
field(A, B) ->
gleam_stdlib:decode_field(A, B).
+
+element(A, B) ->
+ gleam_stdlib:decode_element(A, B).
diff --git a/gen/test/gleam@dynamic_test.erl b/gen/test/gleam@dynamic_test.erl
index d233dbc..ec559b5 100644
--- a/gen/test/gleam@dynamic_test.erl
+++ b/gen/test/gleam@dynamic_test.erl
@@ -1,7 +1,7 @@
-module(gleam@dynamic_test).
-compile(no_auto_import).
--export([string_test/0, int_test/0, float_test/0, thunk_test/0, bool_test/0, atom_test/0, list_test/0, field_test/0]).
+-export([string_test/0, int_test/0, float_test/0, thunk_test/0, bool_test/0, atom_test/0, list_test/0, field_test/0, element_test/0]).
string_test() ->
gleam@expect:equal(
@@ -168,3 +168,29 @@ field_test() ->
),
gleam@expect:is_error(gleam@dynamic:field(gleam@dynamic:from(1), OkAtom)),
gleam@expect:is_error(gleam@dynamic:field(gleam@dynamic:from([]), [])).
+
+element_test() ->
+ {ok, OkAtom} = gleam@atom:from_string(<<"ok">>),
+ {ok, ErrorAtom} = gleam@atom:from_string(<<"ok">>),
+ OkOneStruct = {OkAtom, 1},
+ gleam@expect:equal(
+ gleam@dynamic:element(gleam@dynamic:from(OkOneStruct), 0),
+ {ok, gleam@dynamic:from(OkAtom)}
+ ),
+ gleam@expect:equal(
+ gleam@dynamic:element(gleam@dynamic:from(OkOneStruct), 1),
+ {ok, gleam@dynamic:from(1)}
+ ),
+ gleam@expect:is_error(
+ gleam@dynamic:element(gleam@dynamic:from(OkOneStruct), 2)
+ ),
+ gleam@expect:is_error(
+ gleam@dynamic:element(gleam@dynamic:from(OkOneStruct), -1)
+ ),
+ gleam@expect:is_error(gleam@dynamic:element(gleam@dynamic:from(1), 0)),
+ gleam@expect:is_error(
+ gleam@dynamic:element(
+ gleam@dynamic:from(gleam@map:insert(gleam@map:new(), 1, OkAtom)),
+ 0
+ )
+ ).
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam
index 8086aeb..0660a67 100644
--- a/src/gleam/dynamic.gleam
+++ b/src/gleam/dynamic.gleam
@@ -48,3 +48,6 @@ pub fn list(from dynamic, containing decoder_type) {
pub external fn field(from: Dynamic, named: a) -> Result(Dynamic, String)
= "gleam_stdlib" "decode_field"
+
+pub external fn element(from: Dynamic, position: Int) -> Result(Dynamic, String)
+ = "gleam_stdlib" "decode_element"
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index 8a4a290..abfdfbb 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -6,7 +6,7 @@
atom_create_from_string/1, atom_to_string/1, map_get/2,
iodata_append/2, iodata_prepend/2, identity/1, decode_int/1,
decode_string/1, decode_bool/1, decode_float/1, decode_thunk/1, decode_atom/1,
- decode_list/1, decode_field/2, parse_int/1, parse_float/1, compare_strings/2]).
+ decode_list/1, decode_field/2, decode_element/2, parse_int/1, parse_float/1, compare_strings/2]).
expect_equal(Actual, Expected) -> ?assertEqual(Expected, Actual).
expect_not_equal(Actual, Expected) -> ?assertNotEqual(Expected, Actual).
@@ -70,6 +70,18 @@ decode_field(Data, Key) ->
decode_error_msg(io_lib:format("a map with key `~p`", [Key]), Data)
end.
+decode_element(Data, Position) ->
+ case catch element(Position + 1, Data) of
+ {'EXIT', _Reason} ->
+ {error, nil};
+
+ Value ->
+ {ok, Value};
+
+ _ ->
+ {error, nil}
+ end.
+
parse_int(String) ->
case string:to_integer(binary:bin_to_list(String)) of
{Integer, []} ->
diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam
index f840ce8..96db8c1 100644
--- a/test/gleam/dynamic_test.gleam
+++ b/test/gleam/dynamic_test.gleam
@@ -221,3 +221,40 @@ pub fn field_test() {
|> dynamic.field(_, [])
|> expect.is_error
}
+
+pub fn element_test() {
+ let Ok(ok_atom) = atom.from_string("ok")
+ let Ok(error_atom) = atom.from_string("ok")
+ let ok_one_struct = struct(ok_atom, 1)
+
+ ok_one_struct
+ |> dynamic.from
+ |> dynamic.element(_, 0)
+ |> expect.equal(_, Ok(dynamic.from(ok_atom)))
+
+ ok_one_struct
+ |> dynamic.from
+ |> dynamic.element(_, 1)
+ |> expect.equal(_, Ok(dynamic.from(1)))
+
+ ok_one_struct
+ |> dynamic.from
+ |> dynamic.element(_, 2)
+ |> expect.is_error
+
+ ok_one_struct
+ |> dynamic.from
+ |> dynamic.element(_, -1)
+ |> expect.is_error
+
+ 1
+ |> dynamic.from
+ |> dynamic.element(_, 0)
+ |> expect.is_error
+
+ map.new()
+ |> map.insert(_, 1, ok_atom)
+ |> dynamic.from
+ |> dynamic.element(_, 0)
+ |> expect.is_error
+}