const eql = std.mem.eql; const expect = std.testing.expect; const std = @import("std"); const ComplexTypeTag = enum { ok, not_ok }; const ComplexType = union(ComplexTypeTag) { ok: u8, not_ok: void }; test "switch on tagged union" { const c = ComplexType{ .ok = 42 }; expect(@as(ComplexTypeTag, c) == ComplexTypeTag.ok); switch (c) { ComplexTypeTag.ok => |value| expect(value == 42), ComplexTypeTag.not_ok => unreachable, } } test "@TagType" { expect(@TagType(ComplexType) == ComplexTypeTag); } test "coerce to enum" { const c1: ComplexType = ComplexType{ .ok = 42 }; const c2: ComplexTypeTag = ComplexType.not_ok; expect(c1 == .ok); expect(c2 == .not_ok); } test "modify tagged union in switch" { var c = ComplexType{ .ok = 42 }; expect(c == .ok); switch (c) { ComplexTypeTag.ok => |*value| value.* += 1, ComplexTypeTag.not_ok => unreachable, } expect(c.ok == 43); } const Variant = union(enum) { int: i32, boolean: bool, // void can be omitted when inferring enum tag type. none, fn truthy(self: Variant) bool { return switch (self) { Variant.int => |x_int| x_int != 0, Variant.boolean => |x_bool| x_bool, Variant.none => false, }; } }; test "union method" { var v1 = Variant{ .int = 420 }; var v2 = Variant{ .boolean = false }; expect(v1.truthy()); expect(!v2.truthy()); } const Small2 = union(enum) { a: i32, b: bool, c: u8 }; test "@tagName" { expect(eql(u8, @tagName(Small2.a), "a")); }