diff --git a/src/event.zig b/src/event.zig index 319ed88..d6888bf 100644 --- a/src/event.zig +++ b/src/event.zig @@ -26,10 +26,11 @@ pub const SystemEvent = union(enum) { focus: bool, }; +/// Merge the two provided `union(enum)` `A` and `B` to a tagged union containing all fields of both tagged unions in `comptime`. +/// Declarations are not supported for `comptime` created types, see https://github.com/ziglang/zig/issues/6709 for details. pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type { - if (!isTaggedUnion(A) or !isTaggedUnion(B)) { - @compileError("Both types for merging tagged unions need to be of type `union(enum)`."); - } + if (!isTaggedUnion(A) or !isTaggedUnion(B)) @compileError("Both types for merging tagged unions need to be of type `union(enum)`."); + const a_fields = @typeInfo(A).@"union".fields; const a_fields_tag = @typeInfo(A).@"union".tag_type.?; const a_enum_fields = @typeInfo(a_fields_tag).@"enum".fields; @@ -54,6 +55,11 @@ pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type { i += 1; } + // NOTE declarations are not supported for `comptime` types: https://github.com/ziglang/zig/issues/6709 + // -> will lead to a compilation error when constructing the tagged union + // at the end of this function in case at least one of the provided tagged + // unions to merge contains declarations (which in this case can only be the + // user provided one) const a_enum_decls = @typeInfo(A).@"union".decls; const b_enum_decls = @typeInfo(B).@"union".decls; var decls: [a_enum_decls.len + b_enum_decls.len]std.builtin.Type.Declaration = undefined; @@ -67,11 +73,9 @@ pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type { j += 1; } - const log2_i = @bitSizeOf(@TypeOf(i)) - @clz(i); - const EventType = @Type(.{ .int = .{ .signedness = .unsigned, - .bits = log2_i, + .bits = @bitSizeOf(@TypeOf(i)) - @clz(i), } }); const Event = @Type(.{ .@"enum" = .{ @@ -89,13 +93,11 @@ pub fn mergeTaggedUnions(comptime A: type, comptime B: type) type { } }); } -// Determine at `comptime` whether the provided type `E` is an `union(enum)`. -pub fn isTaggedUnion(comptime E: type) bool { - switch (@typeInfo(E)) { - .@"union" => |u| { - if (u.tag_type) |_| {} else { - return false; - } +/// Determine at whether the provided type `T` is a tagged union: `union(enum)`. +pub fn isTaggedUnion(comptime T: type) bool { + switch (@typeInfo(T)) { + .@"union" => |u| if (u.tag_type) |_| {} else { + return false; }, else => return false, }