1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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"));
}
|