A SpaceTraders Agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 2a9a563fe6fa56bf372a2fcd7e65ee57a92d7e2a 82 lines 2.1 kB view raw
1pub const fmt = @import("fmt.zig"); 2 3pub const pretty = fmt.pretty; 4 5pub fn CombinedEnum(comptime parent: type) type { 6 const std = @import("std"); 7 const parent_info = @typeInfo(parent).@"struct"; 8 9 var num_fields = 0; 10 var num_enums = 0; 11 12 for (parent_info.decls) |partial| { 13 switch (@typeInfo(@field(parent, partial.name))) { 14 .@"enum" => |e| { 15 num_fields += e.fields.len; 16 num_enums += 1; 17 }, 18 else => {}, 19 } 20 } 21 22 const ConversionMap = struct { 23 start: comptime_int = 0, 24 end: comptime_int = 0, 25 T: type, 26 }; 27 28 var combined: [num_fields]std.builtin.Type.EnumField = undefined; 29 var conv_map: [num_enums]ConversionMap = undefined; 30 31 var idx = 0; 32 var i = 0; 33 34 for (parent_info.decls) |partial| { 35 switch (@typeInfo(@field(parent, partial.name))) { 36 .@"enum" => |e| { 37 conv_map[idx] = .{ 38 .start = i, 39 .end = i + e.fields.len - 1, 40 .T = @field(parent, partial.name), 41 }; 42 43 for (e.fields) |field| { 44 combined[i] = .{ .name = field.name, .value = field.value }; 45 i += 1; 46 } 47 48 idx += 1; 49 }, 50 else => {}, 51 } 52 } 53 54 const combined_enum = @Type(std.builtin.Type{ .@"enum" = .{ 55 .decls = &.{}, 56 .fields = &combined, 57 .tag_type = u8, 58 .is_exhaustive = true, 59 } }); 60 61 const combined_enums = num_enums; 62 const conv_map_const = conv_map; 63 64 return struct { 65 pub const Combined = combined_enum; 66 67 const conversion_map: [combined_enums]ConversionMap = conv_map_const; 68 69 pub fn originalType(value: @TypeOf(Combined)) type { 70 const int_rep: u8 = @intFromEnum(value); 71 72 for (conversion_map) |map| { 73 if (map.start <= int_rep and int_rep <= map.end) return map.T; 74 } 75 } 76 }; 77} 78 79test { 80 const testing = @import("std").testing; 81 testing.refAllDeclsRecursive(@This()); 82}