| ... | @@ -53,12 +53,37 @@ test "std.meta.tagName" { | ... | @@ -53,12 +53,37 @@ test "std.meta.tagName" { |
| 53 | } | 53 | } |
| 54 | | 54 | |
| 55 | pub fn stringToEnum(comptime T: type, str: []const u8) ?T { | 55 | pub fn stringToEnum(comptime T: type, str: []const u8) ?T { |
| 56 | inline for (@typeInfo(T).Enum.fields) |enumField| { | 56 | // Using ComptimeStringMap here is more performant, but it will start to take too |
| 57 | if (mem.eql(u8, str, enumField.name)) { | 57 | // long to compile if the enum is large enough, due to the current limits of comptime |
| 58 | return @field(T, enumField.name); | 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 | test "std.meta.stringToEnum" { | 89 | test "std.meta.stringToEnum" { |