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

**URL:** https://discourse.julialang.org/t/protobuf-enum-namedtuple-or-base-enums-enum-type/80285
**Category:** General Usage
**Tags:** question, enum
**Created:** [April 30, 2022, 4:57am UTC](https://discourse.julialang.org/t/protobuf-enum-namedtuple-or-base-enums-enum-type/80285 "2022-04-30T04:57:18Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)
#### Post date: [April 30, 2022, 4:57am UTC](https://discourse.julialang.org/t/protobuf-enum-namedtuple-or-base-enums-enum-type/80285/1 "2022-04-30T04:57:18Z")

</div>

Hello,  
I have a `enum` type in [Protocol Buffer (ProtoBuf)](https://developers.google.com/protocol-buffers/)

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

```

I want to load and use it in Julia.

Searched online and arrived to [ProtoBuf.jl](https://github.com/JuliaIO/ProtoBuf.jl) package.  
In the [documentation](https://github.com/JuliaIO/ProtoBuf.jl/blob/master/PROTOC.md) 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?**

```julia
# 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.

---

<div class="post-metadata">

### Author: ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)
#### Post date: [May 11, 2022, 4:31am UTC](https://discourse.julialang.org/t/protobuf-enum-namedtuple-or-base-enums-enum-type/80285/2 "2022-05-11T04:31:52Z")

</div>

Converted from one to another:

> [@Call @enumx macro with NamedTuple constant as input](https://discourse.julialang.org/t/call-enumx-macro-with-namedtuple-constant-as-input/80699):
>
> Hi, I have a [NamedTuple](https://github.com/JuliaIO/ProtoBuf.jl/blob/v0.11.5/test/testcodec.jl#L286) and would like to create an [EnumX](https://discourse.julialang.org/t/ann-enumx-jl-improved-enums-for-julia/78096) from it, how can this be done? CC @fredrikekre Specifically, I’m using [ProtoBuf.il](https://github.com/JuliaIO/ProtoBuf.jl) to load an [enum from Protocol Buffers](https://developers.google.com/protocol-buffers/docs/proto#enum). And I want to create a new type using [@enumx macro](https://github.com/fredrikekre/EnumX.jl), where the input to the macro would be the NamedTuple key-value pairs as arguments. Input: const SrcProtoBufEnum = (;[ Symbol("UNIVERSAL") =\> Int32(0), Symbol("WEB") =\> Int32(1), Symbol("IMAGES") =\> Int32(2), Symbol("LOCAL") =\> Int32(3), Symbo…
