Skip to content

Commit c72b23a

Browse files
committed
Index 8
1 parent 2af0691 commit c72b23a

File tree

5 files changed

+35
-6
lines changed

5 files changed

+35
-6
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- The decode API can now index into the first 8 elements of lists.
6+
37
## v0.55.0 - 2025-02-21
48

59
- The performance of `dict.is_empty` has been improved.

src/gleam/dynamic/decode.gleam

+5-5
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ pub opaque type Decoder(t) {
292292
///
293293
/// This function will index into dictionaries with any key type, and if the key is
294294
/// an int then it'll also index into Erlang tuples and JavaScript arrays, and
295-
/// the first two elements of Gleam lists.
295+
/// the first eight elements of Gleam lists.
296296
///
297297
/// # Examples
298298
///
@@ -358,7 +358,7 @@ pub fn run(data: Dynamic, decoder: Decoder(t)) -> Result(t, List(DecodeError)) {
358358
///
359359
/// This function will index into dictionaries with any key type, and if the key is
360360
/// an int then it'll also index into Erlang tuples and JavaScript arrays, and
361-
/// the first two elements of Gleam lists.
361+
/// the first eight elements of Gleam lists.
362362
///
363363
/// # Examples
364364
///
@@ -486,7 +486,7 @@ pub fn decode_error(
486486
///
487487
/// This function will index into dictionaries with any key type, and if the key is
488488
/// an int then it'll also index into Erlang tuples and JavaScript arrays, and
489-
/// the first two elements of Gleam lists.
489+
/// the first eight elements of Gleam lists.
490490
///
491491
/// # Examples
492492
///
@@ -526,7 +526,7 @@ pub fn field(
526526
///
527527
/// This function will index into dictionaries with any key type, and if the key is
528528
/// an int then it'll also index into Erlang tuples and JavaScript arrays, and
529-
/// the first two elements of Gleam lists.
529+
/// the first eight elements of Gleam lists.
530530
///
531531
/// # Examples
532532
///
@@ -570,7 +570,7 @@ pub fn optional_field(
570570
///
571571
/// This function will index into dictionaries with any key type, and if the key is
572572
/// an int then it'll also index into Erlang tuples and JavaScript arrays, and
573-
/// the first two elements of Gleam lists.
573+
/// the first eight elements of Gleam lists.
574574
///
575575
/// # Examples
576576
///

src/gleam_stdlib_decode_ffi.erl

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ index([X | _], 0) ->
66
{ok, {some, X}};
77
index([_, X | _], 1) ->
88
{ok, {some, X}};
9+
index([_, _, X | _], 2) ->
10+
{ok, {some, X}};
11+
index([_, _, _, X | _], 3) ->
12+
{ok, {some, X}};
13+
index([_, _, _, _, X | _], 4) ->
14+
{ok, {some, X}};
15+
index([_, _, _, _, _, X | _], 5) ->
16+
{ok, {some, X}};
17+
index([_, _, _, _, _, _, X | _], 6) ->
18+
{ok, {some, X}};
19+
index([_, _, _, _, _, _, _, X | _], 7) ->
20+
{ok, {some, X}};
921
index(Tuple, Index) when is_tuple(Tuple) andalso is_integer(Index) ->
1022
{ok, try
1123
{some, element(Index + 1, Tuple)}

src/gleam_stdlib_decode_ffi.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function index(data, key) {
1616
}
1717

1818
// The first 3 elements of lists can be indexed
19-
if ((key === 0 || key === 1 || key === 2) && data instanceof List) {
19+
if (Number.isInteger(key) && key < 8 && data instanceof List) {
2020
let i = 0;
2121
for (const value of data) {
2222
if (i === key) return new Ok(new Some(value));

test/gleam/dynamic/decode_test.gleam

+13
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,19 @@ pub fn field_int_index_list_ok_test() {
104104
|> should.equal(#("one", "two"))
105105
}
106106

107+
pub fn field_int_index_big_list_ok_test() {
108+
let decoder = {
109+
use x <- decode.field(6, decode.string)
110+
use y <- decode.field(7, decode.string)
111+
decode.success(#(x, y))
112+
}
113+
114+
dynamic.from(["one", "two", "three", "four", "five", "six", "seven", "eight"])
115+
|> decode.run(decoder)
116+
|> should.be_ok
117+
|> should.equal(#("seven", "eight"))
118+
}
119+
107120
pub fn subfield_not_found_error_test() {
108121
let decoder = {
109122
use name <- decode.subfield(["name"], decode.string)

0 commit comments

Comments
 (0)