I find this part of Zig challenging. I like real interfaces as a language primitive, sue me!
However, I recently just swallowed my pride and try to work by convention: provide a method on the implementation type by the same name as the `anytype` argument. `T.writer()` in this case, `T.allocator()` in others, etc.
Previously trying to battle this, I went about as far as the language would let me attempt to automate the type validation: https://github.com/nilslice/zig-interface
This at least allows you to leverage composition to combine "interfaces" - but the caller still faces the `anytype` issue.
I'd like to re-write this (with admitted of help from Claude!) to follow the stdlib pattern used in things like `std.mem.Allocator`, but I reach for this too infrequently to dedicate the time.
However, I recently just swallowed my pride and try to work by convention: provide a method on the implementation type by the same name as the `anytype` argument. `T.writer()` in this case, `T.allocator()` in others, etc.
Previously trying to battle this, I went about as far as the language would let me attempt to automate the type validation: https://github.com/nilslice/zig-interface
This at least allows you to leverage composition to combine "interfaces" - but the caller still faces the `anytype` issue.
I'd like to re-write this (with admitted of help from Claude!) to follow the stdlib pattern used in things like `std.mem.Allocator`, but I reach for this too infrequently to dedicate the time.