Skip to content

Commit 808eccb

Browse files
committed
Fix table_list_decoder
Previously it relied on dict value ordering (big no no)
1 parent 36af06b commit 808eccb

2 files changed

Lines changed: 48 additions & 16 deletions

File tree

src/glua.gleam

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,14 @@ fn do_table(values: List(#(Value, Value)), lua: Lua) -> #(Value, Lua)
581581
pub fn table_list_decoder(
582582
inner decoder: decode.Decoder(a),
583583
) -> decode.Decoder(List(a)) {
584-
decode.dict(decode.int, decoder) |> decode.map(dict.values)
584+
decode.dict(decode.int, decoder) |> decode.map(list_loop(_, [], 1))
585+
}
586+
587+
fn list_loop(dict: dict.Dict(Int, a), acc: List(a), idx: Int) {
588+
case dict.get(dict, idx) {
589+
Ok(it) -> list_loop(dict, [it, ..acc], idx + 1)
590+
Error(Nil) -> list.reverse(acc)
591+
}
585592
}
586593

587594
/// Encodes a Gleam function into a Lua function.

test/glua_test.gleam

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,46 @@ pub fn get_table_test() {
4444

4545
pub fn table_list_test() {
4646
let list = ["foo", "bar", "baz", "qux"]
47-
glua.run(glua.new(), {
48-
use val <- glua.then(glua.table_list(list |> list.map(glua.string)))
49-
use decoded <- glua.then(glua.dereference(
50-
val,
51-
glua.table_list_decoder(decode.string),
52-
))
53-
assert list == decoded
54-
use decoded <- glua.then(glua.dereference(
55-
val,
56-
decode.dict(decode.int, decode.string),
57-
))
58-
assert dict.to_list(decoded)
59-
== [#(1, "foo"), #(2, "bar"), #(3, "baz"), #(4, "qux")]
60-
glua.success(Nil)
61-
})
47+
let assert Ok(Nil) =
48+
glua.run(glua.new(), {
49+
use val <- glua.then(glua.table_list(list |> list.map(glua.string)))
50+
use decoded <- glua.then(glua.dereference(
51+
val,
52+
glua.table_list_decoder(decode.string),
53+
))
54+
assert list == decoded
55+
use decoded <- glua.then(glua.dereference(
56+
val,
57+
decode.dict(decode.int, decode.string),
58+
))
59+
assert dict.to_list(decoded)
60+
== [#(1, "foo"), #(2, "bar"), #(3, "baz"), #(4, "qux")]
61+
glua.success(Nil)
62+
})
63+
}
64+
65+
pub fn table_list_edge_test() {
66+
let values =
67+
[
68+
#(-1, "qux"),
69+
#(1, "foo"),
70+
#(2, "bar"),
71+
#(4, "baz"),
72+
#(-123, "red herring"),
73+
]
74+
|> list.map(pair.map_first(_, glua.int))
75+
|> list.map(pair.map_second(_, glua.string))
76+
77+
let assert Ok(Nil) =
78+
glua.run(glua.new(), {
79+
use val <- glua.then(glua.table(values))
80+
use decoded <- glua.then(glua.dereference(
81+
val,
82+
glua.table_list_decoder(decode.string),
83+
))
84+
assert decoded == ["foo", "bar"]
85+
glua.success(Nil)
86+
})
6287
}
6388

6489
pub fn sandbox_test() {

0 commit comments

Comments
 (0)