1const expect = @import("std").testing.expect;
2const expectEqual = @import("std").testing.expectEqual;
3const expectEqualStrings = @import("std").testing.expectEqualStrings;
4const mem = @import("std").mem;
5
6// Declare an enum.
7const Type = enum {
8 ok,
9 not_ok,
10};
11
12// Declare a specific enum field.
13const c = Type.ok;
14
15// If you want access to the ordinal value of an enum, you
16// can specify the tag type.
17const Value = enum(u2) {
18 zero,
19 one,
20 two,
21};
22// Now you can cast between u2 and Value.
23// The ordinal value starts from 0, counting up by 1 from the previous member.
24test "enum ordinal value" {
25 try expectEqual(0, @backingInt(Value.zero));
26 try expectEqual(1, @backingInt(Value.one));
27 try expectEqual(2, @backingInt(Value.two));
28}
29
30// You can override the ordinal value for an enum.
31const Value2 = enum(u32) {
32 hundred = 100,
33 thousand = 1000,
34 million = 1000000,
35};
36test "set enum ordinal value" {
37 try expectEqual(100, @backingInt(Value2.hundred));
38 try expectEqual(1000, @backingInt(Value2.thousand));
39 try expectEqual(1000000, @backingInt(Value2.million));
40}
41
42// You can also override only some values.
43const Value3 = enum(u4) {
44 a,
45 b = 8,
46 c,
47 d = 4,
48 e,
49};
50test "enum implicit ordinal values and overridden values" {
51 try expectEqual(0, @backingInt(Value3.a));
52 try expectEqual(8, @backingInt(Value3.b));
53 try expectEqual(9, @backingInt(Value3.c));
54 try expectEqual(4, @backingInt(Value3.d));
55 try expectEqual(5, @backingInt(Value3.e));
56}
57
58// Enums can have methods, the same as structs and unions.
59// Enum methods are not special, they are only namespaced
60// functions that you can call with dot syntax.
61const Suit = enum {
62 clubs,
63 spades,
64 diamonds,
65 hearts,
66
67 pub fn isClubs(self: Suit) bool {
68 return self == Suit.clubs;
69 }
70};
71test "enum method" {
72 const p = Suit.spades;
73 try expect(!p.isClubs());
74}
75
76// An enum can be switched upon.
77const Foo = enum {
78 string,
79 number,
80 none,
81};
82test "enum switch" {
83 const p = Foo.number;
84 const what_is_it = switch (p) {
85 Foo.string => "this is a string",
86 Foo.number => "this is a number",
87 Foo.none => "this is a none",
88 };
89 try expectEqualStrings(what_is_it, "this is a number");
90}
91
92// @typeInfo can be used to access the integer tag type of an enum.
93const Small = enum {
94 one,
95 two,
96 three,
97 four,
98};
99test "std.meta.Tag" {
100 try expectEqual(u2, @typeInfo(Small).@"enum".tag_type);
101}
102
103// @typeInfo tells us the field count and the fields names:
104test "@typeInfo" {
105 try expectEqual(4, @typeInfo(Small).@"enum".field_names.len);
106 try expectEqualStrings(@typeInfo(Small).@"enum".field_names[1], "two");
107}
108
109// @tagName gives a [:0]const u8 representation of an enum value:
110test "@tagName" {
111 try expectEqualStrings(@tagName(Small.three), "three");
112}
113
114// Empty enums are uninstantiable, their tag type is always noreturn.
115const Empty = enum {};
116test "empty enum" {
117 try expectEqual(noreturn, @typeInfo(Empty).@"enum".tag_type);
118}
119
120// test