I’m working on a library for a project targeting Arm Cortex-M. I want to convert a enum value to an integer based on the enum tag name.
For example:
const E = enum {
mul4,
mul8,
mul16,
};
// This should map:
// mul4 -> 4
// mul8 -> 8
// mul16 -> 16
fn mulVal(x: anytype) u32 { ... }
The implementation that ended up working is:
pub fn mulDivValue(mul_or_div: anytype) u32 {
switch (mul_or_div) {
inline else => |tag| {
@setEvalBranchQuota(50000);
// Comptime checks to make sure variant name is translated correctly
const tagName = @tagName(tag);
if (comptime !(std.mem.startsWith(u8, tagName, "div") or std.mem.startsWith(u8, tagName, "mul"))) {
@compileError("enum variant must start with 'div' or 'mul': " ++ tagName);
}
const tagDigits = tagName[3..];
inline for (tagDigits) |c| {
if (comptime !std.ascii.isDigit(c)) @compileError("enum variant must contain only digits after prefix: " ++ tagName);
}
const val = comptime std.fmt.parseUnsigned(u32, tagDigits, 10) catch unreachable;
return val;
},
}
}
With const val = comptime ... it works but removing comptime ends up derefencing an invalid address.
My guess is something related to @tagName but I don’t really understand how it works. I thought I wouldn’t need to force it to comptime.
Why do I need to explicitly mention comptime in val assignment?