ProtoBuf Enum - NamedTuple or Base.Enums.Enum type?

FireCrumb
Sat, 30 Apr 2022 04:57:18 +0000
General Usage

Hello,
I have a enum type in Protocol Buffer (ProtoBuf)

enum Fruit {
    APPLE=1;
    ORANGE=2;
    KIWI=3;
};

I want to load and use it in Julia.

Searched online and arrived to ProtoBuf.jl package.
In the documentation it says:

Enums are declared as Int32 types in the generated code. For every enum, a separate named tuple is generated with fields matching the enum values. The lookup method can be used to verify valid values.

How is it different from Enum type and which is better?

# syntax: proto2
# https://github.com/JuliaIO/ProtoBuf.jl/blob/master/PROTOC.md
const FruitEnum1 = (;[
    Symbol("APPLE") => Int32(1),
    Symbol("ORANGE") => Int32(2),
    Symbol("KIWI") => Int32(3),
]...)

const FruitEnum2 = (;[
    Symbol("APPLE") => Int32(4),
    Symbol("ORANGE") => Int32(5),
    Symbol("KIWI") => Int32(6),
]...)

eat1(x::Symbol) = println("I'm a Fruit $(x) with value: $(FruitEnum1[x])");
eat2(x::Symbol) = println("I'm a Fruit $(x) with value: $(FruitEnum2[x])");

eat1(:APPLE)    # I'm a Fruit APPLE with value: 1
eat2(:APPLE)    # I'm a Fruit APPLE with value: 4
eat1(:BANANA)   # ERROR: type NamedTuple has no field BANANA


# https://docs.julialang.org/en/v1/base/base/#Base.Enums.Enum
@enum FruitEnum3 APPLE=7 ORANGE=8 KIWI=9

eat3(x::FruitEnum3) = println("I'm a Fruit $(x) with value: $(Int(x))");

eat3(APPLE)     # I'm a Fruit APPLE with value: 7

eat3(7)         # MethodError: no method matching eat3(::Int64)
                # Closest candidates are: eat3(::FruitEnum3)

eat2(BANANA)   # ERROR: UndefVarError: BANANA not defined

# ERROR: invalid redefinition of constant ORANGE
@enum FruitEnum4 APPLE=10 ORANGE=11 KIWI=12
eat4(x::FruitEnum4) = println("I'm a Fruit $(x) with value: $(Int(x))");

In the case of NamedTuple from Symbol to Int32 generated by ProtoBuf.jl, we get:

1. Multiple enums can have same name, no collision

2. Lookup using Symbols, can be optimized in compile-time

3. No type enforcement (can’t have function accept only specific enum type)

But in the case of Enum, we get:

1. There is an enforced type for it that can be supplied on fields/parameters.

2. Lookup uses constants, also can be optimized in compile-time.

3. Constants are global, so can’t have multiple enums with same keys.

2 posts - 1 participant