diff options
Diffstat (limited to 'src/util/enum.zig')
-rw-r--r-- | src/util/enum.zig | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/util/enum.zig b/src/util/enum.zig new file mode 100644 index 0000000..216d04e --- /dev/null +++ b/src/util/enum.zig @@ -0,0 +1,56 @@ +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")); +} |