1 /** 2 Internal module for pushing and getting associative arrays. 3 All associative arrays with LuaD compatible key and value types are supported. 4 For tables with heterogeneous key or value types, use $(D Algebraic) (see $(DPMODULE2 conversions,variant)) keys/values or $(DPREF table,LuaTable). 5 For string keys and heterogeneous value types, consider using a $(D struct) (see $(DPMODULE2 conversions,structs)). 6 */ 7 module luad.conversions.assocarrays; 8 9 import luad.c.all; 10 import std.traits; 11 import luad.stack; 12 13 void pushAssocArray(T, U)(lua_State* L, T[U] aa) 14 { 15 assert(aa.length <= int.max, "lua_createtable only supports int.max many elements"); 16 lua_createtable(L, 0, cast(int) aa.length); 17 foreach(key, value; aa) 18 { 19 pushValue(L, key); 20 pushValue(L, value); 21 lua_rawset(L, -3); 22 } 23 } 24 25 T getAssocArray(T)(lua_State* L, int idx) if (isAssociativeArray!T) 26 { 27 T aa; 28 alias typeof(aa.values[0]) ElemType; 29 alias typeof(aa.keys[0]) KeyType; 30 31 lua_pushnil(L); 32 while(lua_next(L, idx < 0? idx - 1 : idx) != 0) 33 { 34 aa[getValue!KeyType(L, -2)] = getValue!ElemType(L, -1); 35 lua_pop(L, 1); 36 } 37 38 return aa; 39 } 40 41 version(unittest) import luad.testing; 42 43 unittest 44 { 45 lua_State* L = luaL_newstate(); 46 scope(success) lua_close(L); 47 luaL_openlibs(L); 48 49 pushValue(L, ["foo": "bar", "hello": "world"]); 50 lua_setglobal(L, "aa"); 51 52 unittest_lua(L, ` 53 assert(aa.foo == "bar") 54 assert(aa.hello == "world") 55 56 aa = {one = 1, two = 2} 57 `); 58 59 lua_getglobal(L, "aa"); 60 auto aa = popValue!(uint[string])(L); 61 assert(aa["one"] == 1); 62 assert(aa["two"] == 2); 63 }