Best way to select implementation based on runtime argument? (dispatch vs. control flow)

Would it make sense to have special enums that can assist runtime dispatch by creating specialized methods for Val?

julia> macro dispatch_enum(basetype, args...)
           name = basetype isa Expr ? basetype.args[1] : basetype
           esc(quote
               @enum($((basetype, args...)...))
               @generated Base.Val(var"#"::$name) = let ifex(enum)=:(if $enum≡var"#"; Val{$enum}() end),
                       enums = collect(values(Base.Enums.Enums.namemap($name))), ret = ifex(enums[1]), expr = ret
                   for enum = enums[2:end];  expr = last(push!(expr.args, ifex(enum)))  end
                   expr.head, expr.args = expr.args[end].head, expr.args[end].args
                   ret
               end
               nothing
           end)
       end
@dispatch_enum (macro with 1 method)

julia> @dispatch_enum foo a b c

julia> methods(Val)
# 2 methods for type constructor:
 [1] Val(var"#"::foo)
     @ Main REPL[1]:5
 [2] Val(x)
     @ essentials.jl:801

julia> @code_warntype Val(a)
MethodInstance for Val(::foo)
  from Val(var"#"::foo) @ Main REPL[1]:5
Arguments
  #self#::Type{Val}
  #::foo
Body::Union{Val{a}, Val{c}, Val{b}}
1 ─ %1  = (Main.a ≡ #)::Bool
└──       goto #3 if not %1
2 ─ %3  = Core.apply_type(Main.Val, Main.a)::Core.Const(Val{a})
│   %4  = (%3)()::Core.Const(Val{a}())
└──       return %4
3 ─ %6  = (Main.c ≡ #)::Bool
└──       goto #5 if not %6
4 ─ %8  = Core.apply_type(Main.Val, Main.c)::Core.Const(Val{c})
│   %9  = (%8)()::Core.Const(Val{c}())
└──       return %9
5 ─ %11 = Core.apply_type(Main.Val, Main.b)::Core.Const(Val{b})
│   %12 = (%11)()::Core.Const(Val{b}())
└──       return %12