How to convert an int to an enum?

There’s @enumToInt builtin for (infailably) converting an enum value to underlying int. Is there something to go in the opposite direction (which naturally needs to be able to fail). I use the following code, is there anything better?

const Hand = enum {
    rock, paper, scissors,

    fn from_int(val: u8) ?Hand {
        inline for (@typeInfo(Hand).Enum.fields) |field, i| {
            if (i == val) return @field(Hand, field.name);
        }
        return null;
    }
};

https://ziglang.org/documentation/0.10.0/#intToEnum

@intToEnum(comptime DestType: type, integer: anytype) DestType
2 Likes

Hm, seems like that still requires me to do range-check on the value, but yeah, clearly an improvementx

not always…

const std = @import("std");

const Enum = enum {
    one,
    two,
};

pub fn main() void {
    const x: u8 = 3;
    const y = @intToEnum(Enum, x);
    std.debug.print("y = {}\n", .{y});
}
$ /opt/zig-0.10/zig build-exe itoe.zig 
itoe.zig:11:15: error: enum 'itoe.Enum' has no tag with value '3'
    const y = @intToEnum(Enum, x);
              ^~~~~~~~~~~~~~~~~~~
itoe.zig:4:14: note: enum declared here
const Enum = enum {

I know this is old, but I had the same problem and the code in here no longer compiles.

But this seems to work:

fn from_int(val: u8) ?Hand {
    return std.meta.intToEnum(@This(), val) catch null;
}
1 Like

@intToEnum was renamed to @enumFromInt, and it was changed to not explicitly take the enum type as a parameter (instead inferring it from the use site). You can write something like const x: MyEnum = @enumFromInt(int_val).

If you want to catch invalid values, then the std.meta function you found is indeed the thing to use.

3 Likes