Suppose the following trait and enum
#[enum_dispatch(Components)]
trait Component {}
struct A;
struct B;
impl Component for A {}
impl Component for B {}
#[enum_dispatch]
enum Components {
A,
B,
}
Now I want to be able to "downcast" an instance of my enum in a generic way, i.e. I want to write
let foo = Components::A(A);
dbg!(foo.downcast::<A>()); // Some(&A) : Option<&A>
dbg!(foo.downcast::<B>()); // None : Option<&A>
Is this possible at all?
Background: I am trying something akin to but not quite like an ECS and trait objects are a bad fit for various reasons, thus I ended up with enum_dispatch. I still need my components in a HashMap though but need to access the inner values with a known type. I also really wish for the type to be a parameter and not part of a function name (i.e. something like foo.downcast_A()) because I'd like to have higher order functions on top of that:
fn apply<C, F>(target: &Components, f: F)
where C: Components, F: FnOnce(C)
{
if let Some(x) = target.downcast::<C>() {
f(x);
}
}
I was able to achieve something similar with macro_rules! but carrying an identifier instead of a typename through a callchain is not very ergonomic.