const std = @import("std"); pub fn enumFieldsSlice(comptime T: type) []const T { var fields: []const T = &[_]T{}; inline for (@typeInfo(T).Enum.fields) |enumField| { fields = fields ++ &[_]T{ @field(T, enumField.name), }; } return fields; } /// Creates an slice of slices with with fields in the given enum. /// Runs `F` for each field in `T` to modify the names in the resulting slice. pub fn enumFieldsStringSlice( comptime T: type, comptime F: ?fn (comptime []const u8) []const u8, ) []const []const u8 { @setEvalBranchQuota(10000); var names: []const []const u8 = &[_][]const u8{}; for (std.meta.fields(T)) |field| { const name = blk: { if (F) |f| break :blk f(field.name); break :blk field.name; }; names = names ++ &[_][]const u8{name}; } return names; } const TestEnum = enum { A_A, B_B, }; fn replaceUnderscores(comptime o: []const u8) []const u8 { var name: [o.len]u8 = undefined; _ = std.mem.replace(u8, o, &[_]u8{'_'}, &[_]u8{'-'}, &name); return &name; } test "enumFieldsSlice" { const fields = comptime enumFieldsSlice(TestEnum); try std.testing.expect(fields.len == 2); try std.testing.expect(fields[@enumToInt(TestEnum.A_A)] == TestEnum.A_A); try std.testing.expect(fields[@enumToInt(TestEnum.B_B)] == TestEnum.B_B); } test "enumFieldsStringSlice" { const fields = comptime enumFieldsStringSlice(TestEnum, replaceUnderscores); const a = TestEnum.A_A; const b = TestEnum.B_B; try std.testing.expect(fields.len == 2); try std.testing.expect(std.mem.eql(u8, fields[@enumToInt(a)], "A-A")); try std.testing.expect(std.mem.eql(u8, fields[@enumToInt(b)], "B-B")); }