summaryrefslogtreecommitdiff
path: root/src/util/enum.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/enum.zig')
-rw-r--r--src/util/enum.zig56
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"));
+}