1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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"));
}
|