I also would like this kind of functionality for all my Enums, but I don’t like declaring constants for every enum.
I’ve arrived so far on the solution below. But I should probably write my own enum macro, similar to this discussion on enum dot access:
function get_instance(enum::DataType, str::String)
idx = findfirst(x -> x==str, instance_names(enum))
if idx == nothing
throw(ArgumentError("invalid value for Enum $enum: $str"))
else
return enum(idx-1)
end
end
instance_names(enum::DataType) = string.(instances(enum))
@enum Fruits begin
apple
pear
banana
end
Fruits(str::String) = get_instance(Fruits, str)
Base.convert(::Type{Fruits}, str::String) = Fruits(str)
Now this works fine:
julia> Fruits("banana")
banana::Fruits = 2
julia> Fruits("monkey")
ERROR: ArgumentError: invalid value for Enum Fruits: monkey
I had to add the Base.convert since I am creating an enum instance from a constructor:
struct FruitBowl
fruit::Fruits
end
julia> bowl = FruitBowl("banana")
julia> bowl.fruit
banana::Fruits = 2
I do not know why I could not dispatch on the Enum type though. typeof(Fruits) returned Datatype, not Enum.