2022-10-20 15:04:28 +02:00
|
|
|
const std = @import("std");
|
2023-03-07 16:34:13 +01:00
|
|
|
const ffi = @import("ffi.zig");
|
|
|
|
const c = ffi.c;
|
2022-10-20 15:04:28 +02:00
|
|
|
|
|
|
|
pub fn luaPushAny(l: *c.lua_State, x: anytype) void {
|
|
|
|
const T = @TypeOf(x);
|
|
|
|
|
|
|
|
switch (@typeInfo(T)) {
|
|
|
|
.Void, .Null => c.lua_pushnil(l),
|
2023-06-25 23:57:51 +02:00
|
|
|
.Bool => c.lua_pushboolean(l, @intCast(c_int, @intFromBool(x))),
|
2022-10-20 15:04:28 +02:00
|
|
|
.Int, .ComptimeInt => c.lua_pushinteger(l, @intCast(c_int, x)),
|
|
|
|
.Float, .ComptimeFloat => c.lua_pushnumber(l, @floatCast(c.lua_Number, x)),
|
|
|
|
.Pointer => |P| {
|
|
|
|
switch (P.size) {
|
|
|
|
.One => {
|
|
|
|
if (T == c.lua_CFunction or
|
|
|
|
T == @typeInfo(c.lua_CFunction).Optional.child)
|
2023-03-07 16:34:13 +01:00
|
|
|
{
|
|
|
|
c.lua_pushcfunction(l, x);
|
|
|
|
} else if (@typeInfo(P.child) == .Array) {
|
|
|
|
luaPushAny(l, @as([]const std.meta.Elem(P.child), x));
|
|
|
|
} else {
|
2022-10-20 15:04:28 +02:00
|
|
|
luaPushAny(l, x.*);
|
2023-03-07 16:34:13 +01:00
|
|
|
}
|
2022-10-20 15:04:28 +02:00
|
|
|
},
|
|
|
|
.Slice => {
|
|
|
|
if (P.child == u8) {
|
2023-03-07 16:34:13 +01:00
|
|
|
ffi.luaPushString(l, x);
|
2022-10-20 15:04:28 +02:00
|
|
|
} else {
|
|
|
|
c.lua_createtable(l, x.len, 0);
|
|
|
|
|
2023-02-22 19:24:14 +01:00
|
|
|
for (x, 1..) |element, i| {
|
2022-10-20 15:04:28 +02:00
|
|
|
luaPushAny(l, element);
|
2023-02-22 19:24:14 +01:00
|
|
|
c.lua_rawseti(l, -2, i);
|
2022-10-20 15:04:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
.C => {
|
|
|
|
if (P.child != u8)
|
|
|
|
@compileError("luaPushAny doesn't support " ++ @typeName(T));
|
|
|
|
|
|
|
|
c.lua_pushstring(l, x);
|
|
|
|
},
|
|
|
|
.Many => {
|
|
|
|
if (P.child != u8)
|
|
|
|
@compileError("luaPushAny doesn't support " ++ @typeName(T));
|
|
|
|
|
|
|
|
c.lua_pushstring(l, x);
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
.Array => luaPushAny(l, &x),
|
|
|
|
.Struct => |S| {
|
|
|
|
if (comptime std.meta.trait.hasFn("luaPush")(T)) {
|
|
|
|
return x.luaPush(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (S.is_tuple) {
|
|
|
|
c.lua_createtable(l, S.fields.len, 0);
|
|
|
|
|
2023-02-22 19:24:14 +01:00
|
|
|
inline for (S.fields, 1..) |Field, i| {
|
2022-10-20 15:04:28 +02:00
|
|
|
luaPushAny(l, @field(x, Field.name));
|
2023-02-22 19:24:14 +01:00
|
|
|
c.lua_rawseti(l, -2, i);
|
2022-10-20 15:04:28 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
c.lua_createtable(l, 0, S.fields.len);
|
|
|
|
|
|
|
|
inline for (S.fields) |Field| {
|
|
|
|
luaPushAny(l, @field(x, Field.name));
|
2023-06-25 23:57:51 +02:00
|
|
|
c.lua_setfield(l, -2, (Field.name ++ &[_]u8{0}).ptr);
|
2022-10-20 15:04:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
.Optional => {
|
|
|
|
if (x) |val| {
|
|
|
|
luaPushAny(l, val);
|
|
|
|
} else {
|
|
|
|
c.lua_pushnil(l);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
.Enum, .EnumLiteral => c.lua_pushstring(l, @tagName(x)),
|
|
|
|
.Type => {
|
|
|
|
if (@hasDecl(x, "luaPush")) {
|
|
|
|
return x.luaPush(l);
|
|
|
|
}
|
|
|
|
@compileError("luaPushAny doesn't support " ++ @typeName(T));
|
|
|
|
},
|
|
|
|
else => @compileError("luaPushAny doesn't support " ++ @typeName(T)),
|
|
|
|
}
|
|
|
|
}
|