Is there a way to extend enums with more values?

I particularly am looking into:

// in lib
pub const STATUS_SIGNALS = enum(u8) {
    EXIT_SUCCESS = 0,
    EXIT_FAILURE = 1,
    EXIT_TIMEDOUT = 124, // Time expired before child completed.
    EXIT_CANCELED = 125, // Internal error prior to exec attempt.
    EXIT_CANNOT_INVOKE = 126, // Program located, but not usable.
    EXIT_ENOENT = 127, // Could not find program to exec.

    pub fn exit(self: STATUS_SIGNALS) u8 {
        // some code before exit ...

        std.posix.exit(@intFromEnum(self));
    }
};

// in program
const TTY_STATUS_SIGNALS = enum(u8) {
    // also note the repeating value here
    TTY_STDIN_NOTTY = 1,
    TTY_FAILURE = 2,
    TTY_WRITE_ERROR = 3,
};

Im also open to other options, but im still curious about title.
I dont actually think its posible with enums.
Also note the repeating value 1.

Talking about other options maybe im coming at this from an outdated perspective and it would be best to come with error sets, but dont know where to start with that

On the topic of repeated enum values, I believe it is not allowed to have “field aliases”. There’s a whole big long debate in a related github issue:

enums should disallow multiple enumerations with the same value · Issue #2115 · ziglang/zig · GitHub

For merging two enums, it should be possible to do some comptime magic with std.meta.fields() to create a new enum which contains all the fields from any number of enums. Keep in mind that you’ll very likely get a compiler error if any of the values are the same. Creating enums at comptime looks like a good bet, although I don’t know how recent it is.

3 Likes

On the other hand, you can use your enum to make a union with some method (tag?) to return a value. Then you can make multiple enum values give you the same value.

const MyE = enum {
    one,
    two,
    default,
};

const MyU = union(MyE) {
    one,
    two,
    default,

    pub fn tag(self: MyU) u8 {
        return switch(self) {
            .one => 1,
            .two => 2,
            .default => 1, // let's say the default is also 1
        };
    }
};

Can you clarify what you mean with this example?

I think this example would be clearer if the union fields actually had values corresponding to different enums, instead of being void fields. (Otherwise MyU also could just be an enum with a tag method?)

You are right, you don’t need a union.

This is a very good read