about summary refs log tree commit diff
path: root/lang/zig/enums.zig
blob: 4b6a7a87a4771c7a9fbf4f0fa61e8bdb0ae80e14 (plain) (blame)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const std = @import("std");
const expect = std.testing.expect;
const eql = std.mem.eql;

// Declare an enum.
const Type = enum { ok, not_ok };

// Declare a specific instance of the enum variant.
const c = Type.ok;

test "enum ordinal value" {
    // If you want access to the ordinal value of an enum,
    // you can specify the tag type.
    const Value = enum(u2) { zero, one, two };
    const Value1 = enum { zero, one, two };

    // Now you can cast between u2 and Value.
    // The ordinal value starts from 0, counting up for each member.
    expect(@enumToInt(Value.zero) == 0);
    expect(@enumToInt(Value.one) == 1);
    expect(@enumToInt(Value.two) == 2);

    // Tag type needs not be explicitly specified:
    expect(@enumToInt(Value1.zero) == 0);
    expect(@enumToInt(Value1.one) == 1);
    expect(@enumToInt(Value1.two) == 2);
}

// You can override the ordinal value for an enum.
const Value2 = enum(u32) { hundred = 100, thousand = 1000, million = 1000000 };
test "set enum ordinal value" {
    expect(@enumToInt(Value2.hundred) == 100);
    expect(@enumToInt(Value2.thousand) == 1000);
    expect(@enumToInt(Value2.million) == 1000000);
}

// Enums can have methods, the same as structs and unions.
// Enum methods are not special, they are only namespaced
// functions that you can call with dot syntax.
const Suit = enum {
    clubs,
    spades,
    diamonds,
    hearts,

    pub fn isClubs(self: Suit) bool {
        return self == Suit.clubs;
    }
};
test "enum method" {
    const p = Suit.spades;
    expect(!p.isClubs());
}

// An enum variant of different types can be switched upon.
const Foo = enum {
    string,
    number,
    none,
};
test "enum variant switch" {
    const p = Foo.number;
    const what_is_it = switch (p) {
        Foo.string => "this is a string",
        Foo.number => "this is a number",
        Foo.none => "this is a none",
    };
    expect(eql(u8, what_is_it, "this is a number"));
}

// @TagType can be used to access the integer tag type of an enum.
const Small = enum { one, two, three, four };
test "@TagType" {
    expect(@TagType(Small) == u2);
}

// @typeInfo tells us the field count and the fields names:
test "@typeInfo" {
    expect(@typeInfo(Small).Enum.fields.len == 4);
    expect(eql(u8, @typeInfo(Small).Enum.fields[1].name, "two"));
}

// @tagName gives a []const u8 representation of an enum value:
test "@tagName" {
    expect(eql(u8, @tagName(Small.three), "three"));
}