| ... | ... | @@ -53,12 +53,37 @@ test "std.meta.tagName" { |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | pub fn stringToEnum(comptime T: type, str: []const u8) ?T { |
| 56 | | inline for (@typeInfo(T).Enum.fields) |enumField| { |
| 57 | | if (mem.eql(u8, str, enumField.name)) { |
| 58 | | return @field(T, enumField.name); |
| 56 | // Using ComptimeStringMap here is more performant, but it will start to take too |
| 57 | // long to compile if the enum is large enough, due to the current limits of comptime |
| 58 | 	// performance when doing things like constructing lookup maps at comptime. |
| 59 | // TODO The '100' here is arbitrary and should be increased when possible: |
| 60 | // - https://github.com/ziglang/zig/issues/4055 |
| 61 | // - https://github.com/ziglang/zig/issues/3863 |
| 62 | if (@typeInfo(T).Enum.fields.len <= 100) { |
| 63 | const kvs = comptime build_kvs: { |
| 64 | // In order to generate an array of structs that play nice with anonymous |
| 65 | // list literals, we need to give them "0" and "1" field names. |
| 66 | // TODO https://github.com/ziglang/zig/issues/4335 |
| 67 | const EnumKV = struct { |
| 68 | @"0": []const u8, |
| 69 | @"1": T, |
| 70 | }; |
| 71 | var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined; |
| 72 | inline for (@typeInfo(T).Enum.fields) |enumField, i| { |
| 73 | kvs_array[i] = .{.@"0" = enumField.name, .@"1" = @field(T, enumField.name)}; |
| 74 | } |
| 75 | break :build_kvs kvs_array[0..]; |
| 76 | }; |
| 77 | const map = std.ComptimeStringMap(T, kvs); |
| 78 | return map.get(str); |
| 79 | } else { |
| 80 | inline for (@typeInfo(T).Enum.fields) |enumField| { |
| 81 | if (mem.eql(u8, str, enumField.name)) { |
| 82 | return @field(T, enumField.name); |
| 83 | } |
| 59 | 84 | } |
| 85 | return null; |
| 60 | 86 | } |
| 61 | | return null; |
| 62 | 87 | } |
| 63 | 88 | |
| 64 | 89 | test "std.meta.stringToEnum" { |