Skip to content

Instantly share code, notes, and snippets.

@mlarouche
Last active February 26, 2020 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mlarouche/3f898a80cff37705851638911a30a94a to your computer and use it in GitHub Desktop.
Save mlarouche/3f898a80cff37705851638911a30a94a to your computer and use it in GitHub Desktop.
How to call a function via reflection?
fn findImageFormat(inStream: *ImageInStream, seekStream: *ImageSeekStream) !ImageFormat {
const allFuncs = comptime blk: {
// TODO: Use ArrayList when Zig support compile-time allocator
var result:[16]fn(inStream: *ImageInStream, seekStream: *ImageSeekStream) anyerror!ImageFormat = undefined;
var index:usize = 0;
inline for (std.meta.declarations(AllImageFormats)) |decl| {
switch(decl.data) {
.Type => |entryType| {
const entryTypeInfo = @typeInfo(entryType);
if (entryTypeInfo== .Struct) {
inline for (entryTypeInfo.Struct.decls) |structEntry| {
if (std.mem.eql(u8, structEntry.name, "formatDetect")) {
result[index] = @field(entryType, "formatDetect");
index += 1;
}
}
}
},
else => {}
}
}
break :blk result[0..index];
};
for (allFuncs) |func| {
const foundImageFormat = func(inStream, seekStream) catch |err| {
continue;
};
return foundImageFormat;
}
return errors.ImageFormatInvalid;
}
fn findImageFormat(inStream: *ImageInStream, seekStream: *ImageSeekStream) !ImageFormat {
inline for (@typeInfo(AllImageFormats).Struct.decls) |rootEntry| {
switch(rootEntry.data) {
.Type => |entryType| {
const entryTypeInfo = @typeInfo(entryType);
if (entryTypeInfo== .Struct) {
inline for (entryTypeInfo.Struct.decls) |structEntry| {
if (std.mem.eql(u8, structEntry.name, "formatDetect")) {
@call(.{}, structEntry.data.Fn.fn_type, .{inStream, seekStream});
// const foundImageFormat = @call(.{}, @typeInfo(structEntry.data.Fn.fn_type).Fn, .{inStream, seekStream}) catch|err| {
// continue;
// };
}
}
}
},
else => {}
}
}
return errors.ImageFormatInvalid;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment