Skip to content

Commit baba73e

Browse files
authored
update toAnyAlloc to support non-const slices (#102)
* remove const qualifier if required * verify if struct field is optional when lua field is nil * create a copy of the string if mutation is necessary * use dupe and dupeZ
1 parent 94b581b commit baba73e

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

src/lib.zig

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,10 +3214,18 @@ pub const Lua = opaque {
32143214
const string: [*:0]const u8 = try lua.toString(index);
32153215
const end = std.mem.indexOfSentinel(u8, 0, string);
32163216

3217-
if (info.sentinel == null) {
3218-
return string[0..end];
3217+
if (!info.is_const) {
3218+
if (!allow_alloc) {
3219+
@compileError("toAny cannot allocate memory, try using toAnyAlloc");
3220+
}
3221+
3222+
if (info.sentinel != null) {
3223+
return try a.?.dupeZ(u8, string[0..end]);
3224+
} else {
3225+
return try a.?.dupe(u8, string[0..end]);
3226+
}
32193227
} else {
3220-
return string[0..end :0];
3228+
return if (info.sentinel == null) string[0..end] else string[0..end :0];
32213229
}
32223230
} else switch (info.size) {
32233231
.Slice, .Many => {
@@ -3324,6 +3332,7 @@ pub const Lua = opaque {
33243332
var result: T = undefined;
33253333

33263334
inline for (@typeInfo(T).Struct.fields) |field| {
3335+
const field_type_info = comptime @typeInfo(field.type);
33273336
const field_name = comptime field.name ++ "";
33283337
_ = lua.pushStringZ(field_name);
33293338

@@ -3332,7 +3341,7 @@ pub const Lua = opaque {
33323341
if (lua_field_type == .nil) {
33333342
if (field.default_value) |default_value| {
33343343
@field(result, field.name) = @as(*const field.type, @ptrCast(@alignCast(default_value))).*;
3335-
} else {
3344+
} else if (field_type_info != .Optional) {
33363345
return error.LuaTableMissingValue;
33373346
}
33383347
} else {

src/tests.zig

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,6 +2446,46 @@ test "toAny struct" {
24462446
));
24472447
}
24482448

2449+
test "toAny mutable string" {
2450+
var lua = try Lua.init(&testing.allocator);
2451+
defer lua.deinit();
2452+
2453+
//[] u8
2454+
_ = lua.pushStringZ("hello world");
2455+
const parsed = try lua.toAnyAlloc([]u8, -1);
2456+
defer parsed.deinit();
2457+
2458+
const my_string = parsed.value;
2459+
2460+
try testing.expect(std.mem.eql(u8, my_string, "hello world"));
2461+
}
2462+
2463+
test "toAny mutable string in struct" {
2464+
var lua = try Lua.init(&testing.allocator);
2465+
defer lua.deinit();
2466+
2467+
const MyType = struct {
2468+
name: []u8,
2469+
sentinel: [:0]u8,
2470+
bar: bool,
2471+
};
2472+
try lua.doString("value = {[\"name\"] = \"hi\", [\"sentinel\"] = \"ss\", [\"bar\"] = false}");
2473+
const lua_type = try lua.getGlobal("value");
2474+
try testing.expect(lua_type == .table);
2475+
const parsed = try lua.toAnyAlloc(MyType, 1);
2476+
defer parsed.deinit();
2477+
2478+
const my_struct = parsed.value;
2479+
2480+
var name: [2]u8 = .{ 'h', 'i' };
2481+
var sentinel: [2:0]u8 = .{ 's', 's' };
2482+
2483+
try testing.expectEqualDeep(
2484+
MyType{ .name = &name, .sentinel = &sentinel, .bar = false },
2485+
my_struct,
2486+
);
2487+
}
2488+
24492489
test "toAny struct recursive" {
24502490
var lua = try Lua.init(&testing.allocator);
24512491
defer lua.deinit();

0 commit comments

Comments
 (0)