fn WrappedStruct(comptime in_type: type) type {
const type_info = @typeInfo(in_type);
if (type_info != .Struct) {
@compileError("expected struct argument, found " ++ @typeName(in_type));
}
const struct_info = type_info.Struct;
const fields_info = struct_info.fields;
comptime var fields: [struct_info.decls.len + fields_info.len]std.builtin.Type.StructField = undefined;
comptime var fields_idx = 0;
inline for (fields_info) |field| {
fields[fields_idx] = field;
fields_idx += 1;
}
inline for (struct_info.decls) |decl| {
const decl_as_field = @field(in_type, decl.name);
const decl_type = @TypeOf(decl_as_field);
const decl_type_info = @typeInfo(decl_type);
// convert all the pub declaration into comptime field?
fields[fields_idx] = .{
.name = decl.name,
.type = decl_type,
.default_value = &decl_as_field,
.is_comptime = true,
.alignment = 0,
};
if (decl_type_info == .Fn) {
fields[fields_idx].decl_as_field = ;// generate new body?
}
fields_idx += 1;
}
return @Type(.{
.Struct = .{ .layout = .Auto, .fields = fields[0..], .decls = &.{}, .is_tuple = false, .backing_integer = null },
});
}
fn foo_wrapper() void {
std.debug.print("was called in between\n", .{});
}
const SomeStruct = struct {
pub fn foo(_: @This()) void {
std.debug.print("Foo\n", .{});
}
}
const WrappedStruct = Wrapped(SomeStruct);
the goal is to somehow create an identical struct of the given struct with all itâs Type Declaration and other stuff and also to call this foo_wrapper
function before calling any other public function of the given struct type.
@AndrewCodeDev has given some headstarts in my help request post.
An example by @AndrewCodeDev where a function that returns void and take a tuple as an argument but is not part of any Struct type namespace:
const std = @import("std");
const builtin = @import("builtin");
fn FunctionWrapper(func: anytype) type {
return struct {
// anytype makes it a member function
pub fn call(args: anytype) void {
std.debug.print("\nHello, Wrapper!\n", .{});
@call(.always_inline, func, args);
}
};
}
fn WrapperStruct(func: anytype) type {
comptime var fields: [1]std.builtin.Type.StructField = undefined;
const wrapped_call = FunctionWrapper(func).call;
fields[0] = .{
.name = "whatever",
.type = @TypeOf(wrapped_call),
.default_value = wrapped_call,
.is_comptime = true,
.alignment = 0,
};
return @Type(.{
.Struct = .{
.layout = .Auto,
.fields = fields[0..],
.decls = &.{},
.is_tuple = false,
.backing_integer = null
},
});
}
pub fn foo() void {
std.debug.print("\nGoodbye, Wrapper!\n", .{});
}
pub fn main() !void {
const wrapped = WrapperStruct(foo){ };
wrapped.whatever(.{});
}