Funny thing is, I am learning Zig at the moment and had to do just that and was impressed at how clean the solution was:
const my_enum = enum {
one,
two,
three,
pub fn str(self: @This()) []const u8 {
return switch (self) {
inline else => |tag| @tagName(tag),
};
}
}
Inline else means the switch/case is expanded at compile time.