How can I create an `Enum` from a list of `String`s or `Symbol`s?

Viewed 303

Given the list of Strings

my_list = ["Banana", "Orange", "Apple"]

How do I create the "corresponding" Enum object? I am looking for something that looks like

@enum MyEnum my_list # does not work

that is equivalent to

@enum MyEnum Banana Orange Apple
2 Answers

Try this:

julia> Main.eval(Meta.parse("@enum MyEnum $(join(my_list, " "))"))

julia> MyEnum
Enum MyEnum:
Banana = 0
Orange = 1
Apple = 2

I tried to traslate the @enum macro, and i came to the following:

if you create an Enum of name MyEnum and instances a=1,b=2,c=3, the code generated by the @enum macro is:

primitive type MyEnum <: Base.Enums.Enum{Int32} 32 end 
function MyEnum(x::Integer)
    1<=x<=3 || Base.Enums.enum_argument_error(MyEnum,x)
    return Base.bitcast(MyEnum, convert(Int32, x))
end

Base.Enums.namemap(x::Type{MyEnum}) = Dict{Int32,Symbol}(1=>:a,2=>:b,3=>:c)Base.typemin(x::Type{MyEnum}) = MyEnum(1)
Base.typemax(x::Type{MyEnum}) = MyEnum(3)const a = MyEnum(1)
const b = MyEnum(2)
const c = MyEnum(3)
Base.instances(x::Type{MyEnum}) = (a,b,c)

we can proceed as follows, if we have decided the name of the Enum and have a list of Strings:

enum_namemap = Dict(Int32(k)=>v for (k,v) in pairs(Symbol.(my_list)))
const myenum_lo = 1
const myenum_hi = length(enum_namemap)

primitive type MyEnum <: Base.Enums.Enum{Int32} 32 end 
function MyEnum(x::Integer)
    myenum_lo<=x<=myenum_hi || Base.Enums.enum_argument_error(MyEnum,x)
    return Base.bitcast(MyEnum, convert(Int32, x))
end

Base.Enums.namemap(x::Type{MyEnum}) = enum_namemap
Base.typemin(x::Type{MyEnum}) = MyEnum(myenum_lo)
Base.typemax(x::Type{MyEnum}) = MyEnum(myenum_hi)

for (k,v) pairs(enum_namemap)
@eval begin
  const $v= MyEnum($k)
end

const = myenum_instances = ([MyEnum(v) for v in keys(enum_namemap)]...)
@eval begin
  Base.instances(x::Type{MyEnum}) = $myenum_instances 
end

With a list of Symbols, the code is easier as there is not any conversion to Symbols

Sadly, i couldnt provide directly the dict or the list of names to the @enum macro, that would be the easiest form

Related