diff options
author | Nguyễn Gia Phong <mcsinyx@disroot.org> | 2021-02-28 17:18:03 +0700 |
---|---|---|
committer | Nguyễn Gia Phong <mcsinyx@disroot.org> | 2021-02-28 17:18:03 +0700 |
commit | ee9b8fc921f48dc893808e1c9dbfbef321aa362c (patch) | |
tree | 0d0a5247b139ba68d2c2aa2d94e1d631476dbc62 /lang/zig/union-tag.zig | |
parent | 2b91f9554b326aea138bd8a0acbfaa10d9ad59aa (diff) | |
download | cp-ee9b8fc921f48dc893808e1c9dbfbef321aa362c.tar.gz |
[lang/zig] Learn some Zig
Diffstat (limited to 'lang/zig/union-tag.zig')
-rw-r--r-- | lang/zig/union-tag.zig | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lang/zig/union-tag.zig b/lang/zig/union-tag.zig new file mode 100644 index 0000000..6954c73 --- /dev/null +++ b/lang/zig/union-tag.zig @@ -0,0 +1,68 @@ +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")); +} |