Good Afternoon all, I was looking for some feedback on this particular pattern, after moving through the patterns post I couldn’t really find what I was looking for. And even in the Ghostty post I wasn’t really satisfied with what I found. After doing a bit of hacking this is what I came up with and I’d like to get some feedback on how to improve this by some people who have a bit more experience.
My goal in this pattern is to have concrete types that implement a number of different methods, and at compile time pass in the type for each implementation, and then from an enum tag pick the implementation. Also at compile time enforce that all implementations at minimum must implement a method with a particular name and signature. The end result looks something like this:
ConnectionManager(.static, 1024).init(io)
const connection = try self.connectionsManager.interface.add(stream);
I understand that I haven’t created anything unique here, I just can’t find any examples to compare my implementation of the pattern against to see if there is anyway I can clean this up more to use in other places.
const ConnectionManagerInterface = enum { static };
pub fn ConnectionManager(comptime interface: ConnectionManagerInterface, comptime max: usize) type {
return struct {
interface: genUnion(Stream, max),
io: Io,
pub fn init(io: Io) @This() {
return .{ .interface = @unionInit(genUnion(Stream, max), @tagName(interface), .init()), .io = io };
}
pub fn deinit() void {}
fn genUnion(comptime T: type, comptime size: ?usize) type {
const capacity: usize = size orelse 1024;
return union(enum) {
static: BoundedArr(capacity, T),
//dynaimc: std.array_list.Aligned(T, std.mem.Alignment.of(T)),
pub fn add(this: *@This(), value: T) !*T {
switch (this.*) {
inline else => |case| {
return try @constCast(&case).*.add(value);
},
}
}
pub fn remove(this: *@This(), value: T) !usize {
switch (this.*) {
inline else => |case| {
return try @constCast(&case).*.remove(value);
},
}
}
pub fn findIndexFromPointer(this: *@This(), target: *T) !usize {
switch (this.*) {
inline else => |case| {
return try @constCast(&case).*.findIndexFromPointer(target);
},
}
}
};
}
};
}
Thank you for any help you can provide!
edit: You can test the failure to compile by adding in the dynamic enum and uncommenting the dynamic portion because array list doesn’t impliment those methods.