Type Function FieldEnum [src]
Returns an enum with a variant named after each field of T.
Prototype
pub fn FieldEnum(comptime T: type) type
Parameters
T: type
Example
test FieldEnum {
try expectEqualEnum(enum {}, FieldEnum(struct {}));
try expectEqualEnum(enum { a }, FieldEnum(struct { a: u8 }));
try expectEqualEnum(enum { a, b, c }, FieldEnum(struct { a: u8, b: void, c: f32 }));
try expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 }));
const Tagged = union(enum) { a: u8, b: void, c: f32 };
try testing.expectEqual(Tag(Tagged), FieldEnum(Tagged));
const Tag2 = enum { a, b, c };
const Tagged2 = union(Tag2) { a: u8, b: void, c: f32 };
try testing.expect(Tag(Tagged2) == FieldEnum(Tagged2));
const Tag3 = enum(u8) { a, b, c = 7 };
const Tagged3 = union(Tag3) { a: u8, b: void, c: f32 };
try testing.expect(Tag(Tagged3) != FieldEnum(Tagged3));
}
Source
pub fn FieldEnum(comptime T: type) type {
const field_infos = fields(T);
if (field_infos.len == 0) {
return @Type(.{
.@"enum" = .{
.tag_type = u0,
.fields = &.{},
.decls = &.{},
.is_exhaustive = true,
},
});
}
if (@typeInfo(T) == .@"union") {
if (@typeInfo(T).@"union".tag_type) |tag_type| {
for (std.enums.values(tag_type), 0..) |v, i| {
if (@intFromEnum(v) != i) break; // enum values not consecutive
if (!std.mem.eql(u8, @tagName(v), field_infos[i].name)) break; // fields out of order
} else {
return tag_type;
}
}
}
var enumFields: [field_infos.len]std.builtin.Type.EnumField = undefined;
var decls = [_]std.builtin.Type.Declaration{};
inline for (field_infos, 0..) |field, i| {
enumFields[i] = .{
.name = field.name ++ "",
.value = i,
};
}
return @Type(.{
.@"enum" = .{
.tag_type = std.math.IntFittingRange(0, field_infos.len - 1),
.fields = &enumFields,
.decls = &decls,
.is_exhaustive = true,
},
});
}