I’m working on a function that “decamelizes” an error name. So OutOfMemory
becomes “Out of memory”. The messages are generated at
comptime. The problem I’m having is that I can’t get an error from a name within the inline loop responsible for runtime matching. When I tried err == @field(ET, e.name)
, I get “TODO handle inferred error sets here”. So now I’m resorting to string comparison, which seems sort of dumb:
fn getErrorMessage(err: anytype) [:0]const u8 {
@setEvalBranchQuota(200000);
const ET = @TypeOf(err);
inline for (@typeInfo(ET).error_set.?) |e| {
if (std.mem.eql(u8, @errorName(err), e.name)) {
const message = comptime decamelize: {
var cap_count: usize = 0;
for (e.name, 0..) |letter, i| {
if (i > 0 and std.ascii.isUpper(letter)) cap_count += 1;
}
var buffer: [e.name.len + cap_count + 1]u8 = undefined;
var index: usize = 0;
for (e.name, 0..) |letter, i| {
if (std.ascii.isUpper(letter)) {
if (i > 0) {
buffer[index] = ' ';
index += 1;
buffer[index] = std.ascii.toLower(letter);
} else {
buffer[index] = letter;
}
} else {
buffer[index] = letter;
}
index += 1;
}
buffer[index] = 0;
break :decamelize buffer;
};
return @ptrCast(&message);
}
} else unreachable;
}