Files
lunch-games/source/luad/conversions/assocarrays.d
2025-04-29 01:59:15 +02:00

64 lines
1.5 KiB
D

/**
Internal module for pushing and getting associative arrays.
All associative arrays with LuaD compatible key and value types are supported.
For tables with heterogeneous key or value types, use $(D Algebraic) (see $(DPMODULE2 conversions,variant)) keys/values or $(DPREF table,LuaTable).
For string keys and heterogeneous value types, consider using a $(D struct) (see $(DPMODULE2 conversions,structs)).
*/
module luad.conversions.assocarrays;
import luad.c.all;
import std.traits;
import luad.stack;
void pushAssocArray(T, U)(lua_State* L, T[U] aa)
{
assert(aa.length <= int.max, "lua_createtable only supports int.max many elements");
lua_createtable(L, 0, cast(int) aa.length);
foreach(key, value; aa)
{
pushValue(L, key);
pushValue(L, value);
lua_rawset(L, -3);
}
}
T getAssocArray(T)(lua_State* L, int idx) if (isAssociativeArray!T)
{
T aa;
alias typeof(aa.values[0]) ElemType;
alias typeof(aa.keys[0]) KeyType;
lua_pushnil(L);
while(lua_next(L, idx < 0? idx - 1 : idx) != 0)
{
aa[getValue!KeyType(L, -2)] = getValue!ElemType(L, -1);
lua_pop(L, 1);
}
return aa;
}
version(unittest) import luad.testing;
unittest
{
lua_State* L = luaL_newstate();
scope(success) lua_close(L);
luaL_openlibs(L);
pushValue(L, ["foo": "bar", "hello": "world"]);
lua_setglobal(L, "aa");
unittest_lua(L, `
assert(aa.foo == "bar")
assert(aa.hello == "world")
aa = {one = 1, two = 2}
`);
lua_getglobal(L, "aa");
auto aa = popValue!(uint[string])(L);
assert(aa["one"] == 1);
assert(aa["two"] == 2);
}