You can’t add methods or declarations to types created with @Type
if you want to do that you could wrap it in a generic struct instead. Something like:
pub fn Wrapper(comptime T:type) type {
return struct {
const Self = @This();
wrapped: T,
pub fn increment(self:*Self) void {
self.wrapped.counter += 1;
}
...
}
}
If you don’t like the wrapper you also can do it the other way around, embed a generic struct with extra methods in a field of the otherwise unmodified struct:
const BuildOther = struct {
path: [:0]const u8,
command: Command(@This(), "command") = .{},
};
pub fn Command(comptime T: type, comptime field: []const u8) type {
return struct {
const Self = @This();
pub fn print(self: *const Self) void {
// get the struct where the command is embedded within
const parent: *const T = @alignCast(@fieldParentPtr(field, self));
std.debug.print("command print: {}\n", .{parent});
}
};
}
pub fn main() !void {
const b: BuildOther = .{ .path = "" };
b.command.print();
}
This has the benefit of avoiding reconstruction of the original struct, thus you can easily add methods to BuildOther
by just writing them directly in the struct definition, you also can add methods to it like this:
const BuildOther = struct {
path: [:0]const u8,
command: Command(@This(), "command") = .{},
pub const doSomething = DoSomething(SomeType).impl;
};
For that approach look at this topic:
The command field I have used is basically a field-based mixin, the benefit of those is that they can be added via a field that also functions as its own namespace separating the functionality of this mixin from clashing with other possible mixins.
One of the issues with usingnamespace based mixins is that it could cause clashes when used with multiple mixins.
Personally I think it is best to avoid constructing structs based on a “template” struct and instead just write the struct you want directly and possibly adding some methods to it using some of these techniques.
Finally if you really, really want to generate the struct you could use a buildstep to generate the code and then create a module from it and thus you also would be able to generate methods, but I would explore other options first.