I need to dispatch to different Zig log functions, depending on a runtime log level defined by a third party. I decided to switch on the runtime value, assign a function pointer based on that value, then call the function.
fn libusbLogCb(ctx: *libusb.Context, level: libusb.LogLevel, msg: [*c]const u8) callconv(.C) void {
_ = ctx;
const zig_log_fn_ptr = *const fn (comptime []const u8, anytype) void;
const log_fn: zig_log_fn_ptr = switch (level) {
.err => scoped_log.err,
.warn => scoped_log.warn,
.info => scoped_log.info,
.debug => scoped_log.debug,
};
log_fn("{s}", .{msg});
}
const scoped_log = std.log.scoped(.whatever);
Unfortunately it doesn’t work, and I don’t understand why.
error: value with comptime-only type '*const fn (comptime []const u8, anytype) void' depends on runtime control flow
const log_fn: zig_log_fn = switch (level) {
^~~~~~
src/transport.zig:34:44: note: runtime control flow here
const log_fn: zig_log_fn = switch (level) {
^~~~~
src/transport.zig:34:36: note: function is generic
Why is zig_log_fn_ptr
a comptime-only type? Surely there must be some way to do this at runtime? Each switch arm returns a function pointer with the same signature.
And what’s the deal with the “function is generic” note? Which function? So what?
Alternative ways of achieving this are welcome, but I’d still like to understand why my original approach isn’t working.