#function pointer with different signatures in StaticStringMap

1 messages · Page 1 of 1 (latest)

candid gulch
#

Hello there.
I want to generate a StaticStringMap at compile time that acts as a kind of "lookup table" for specific functions. This will later be used as routes for a little web framework.
Usage should look something like this:

library.init(.{
    .{ "GET /", HomePageHandler },
    .{ "GET /user", UserPageHandler },
});

In the init function I generate a Key-Value-List at compile time that I can then later pass to initComptime of StaticStringMap.

const HandlerFn = *const fn (*anyopaque, *anyopaque) *anyopaque;
fn generateKeyValueList(comptime routes: anytype) []struct { []const u8, HandlerFn } {
    comptime {
        var kv_list: [routes.len]struct { []const u8, HandlerFn } = undefined;
        for (routes, 0..) |entry, i| {
            const key = entry.@"0";
            const value: HandlerFn = entry.@"1";
            kv_list[i] = .{ key, value };
        }
        return &kv_list;
    }
}

// ...

const kv_list = generateKeyValueList(routes);
const map = std.StaticStringMap(HandlerFn).initComptime(kv_list);

The problem is:

error: expected type '*const fn (*anyopaque, *anyopaque) *anyopaque', found '*const fn (void, void) []const u8'
            const value: HandlerFn = entry.@"1";
                                     ~~~~~^~~~~
note: pointer type child 'fn (void, void) []const u8' cannot cast into pointer type child 'fn (*anyopaque, *anyopaque) *anyopaque'
note: return type '[]const u8' cannot cast into return type '*anyopaque'
echo viper
#

slices are fat pointers, they carry a length, that would be lost if you cast it, you can still do so but you have to jump through the hoops