Example
test fromInt {
const E1 = enum {
A,
};
const E2 = enum {
A,
B,
};
const E3 = enum(i8) { A, _ };
var zero: u8 = 0;
var one: u16 = 1;
_ = &zero;
_ = &one;
try testing.expect(fromInt(E1, zero).? == E1.A);
try testing.expect(fromInt(E2, one).? == E2.B);
try testing.expect(fromInt(E3, zero).? == E3.A);
try testing.expect(fromInt(E3, 127).? == @as(E3, @enumFromInt(127)));
try testing.expect(fromInt(E3, -128).? == @as(E3, @enumFromInt(-128)));
try testing.expectEqual(null, fromInt(E1, one));
try testing.expectEqual(null, fromInt(E3, 128));
try testing.expectEqual(null, fromInt(E3, -129));
}
Source
pub fn fromInt(comptime E: type, integer: anytype) ?E {
const enum_info = @typeInfo(E).@"enum";
if (!enum_info.is_exhaustive) {
if (std.math.cast(enum_info.tag_type, integer)) |tag| {
return @enumFromInt(tag);
}
return null;
}
// We don't directly iterate over the fields of E, as that
// would require an inline loop. Instead, we create an array of
// values that is comptime-know, but can be iterated at runtime
// without requiring an inline loop.
// This generates better machine code.
for (values(E)) |value| {
if (@intFromEnum(value) == integer) return @enumFromInt(integer);
}
return null;
}