#Can I have something like `anytype` for struct fields?

1 messages · Page 1 of 1 (latest)

hasty basin
#

Here's the situation I'm dealing with:

test {
    var council = try MappingCouncil.init(testing_allocator);
    defer council.deinit();

    const TestCtx = struct {
        value: u16 = 0,
        fn addOne(ctx_: *anyopaque, _: ?*anyopaque) !void {
            var ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
            ctx.value += 1;
        }
        fn addTen(ctx_: *anyopaque, _: ?*anyopaque) !void {
            var ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
            ctx.value += 10;
        }
        fn add(ctx_: *anyopaque, add_by_: ?*anyopaque) !void {
            var ctx = @as(*@This(), @ptrCast(@alignCast(ctx_)));
            const add_by = @as(*u16, @ptrCast(@alignCast(add_by_)));
            ctx.value += add_by.*;
        }
        fn print(_: *anyopaque, str_: ?*anyopaque) !void {
            const str = @as([*]const u8, @ptrCast(@alignCast(str_)));
            std.debug.print("str: {s}\n", .{str});
        }
    };
    var ctx = TestCtx{};
    try eq(0, ctx.value);

    // these works
    try council.map("normal", &[_]Key{.a}, .{ .f = TestCtx.addOne, .ctx = &ctx });
    try council.map("normal", &[_]Key{.b}, .{ .f = TestCtx.addTen, .ctx = &ctx });


    var add_by: u16 = 100; // this works
    try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.add, .ctx = &ctx, .args = &add_by });

    var str = "hello!"; // this doesn't work at all
    try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.add, .ctx = &ctx, .args = &str }); 


    try council.activate("normal", hash(&[_]Key{.a}));
    try eq(1, ctx.value);

    try council.activate("normal", hash(&[_]Key{.a}));
    try eq(2, ctx.value);

    try council.activate("normal", hash(&[_]Key{.b}));
    try eq(12, ctx.value);

    try council.activate("normal", hash(&[_]Key{.c}));
    try eq(112, ctx.value);
}

I'm struggling with "saving" function arguments into the Callback struct, since Zig no longer allow anytype struct fields.

#

I want to call something like this directly, without any additional variables:

try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.add, .ctx = &ctx, .args = 100 });
#
try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.add, .ctx = &ctx, .args = "hello" });
#

Is there a way to have a nice API like that? tyvm

#

as it stands right now, I'd have to use a tagged union for Callback struct, which is very annoying whenever I want to add a new type of function calback.

#

ATM I can't have args directly

src/keyboard/input_processor.zig|210 col 79| error: expected type '?*anyopaque', found 'comptime_int'
||     try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.add, .ctx = &ctx, .args = 100 });
#
src/keyboard/input_processor.zig|212 col 79| error: expected type '?*anyopaque', found '*const [6:0]u8'
||     try council.map("normal", &[_]Key{.c}, .{ .f = TestCtx.print, .ctx = &ctx, .args = "hello!" });