Conditional Cast of trait objects

Hi all,

I have a crazy idea and wonder if it could work.

tl;dr

Cast a trait object to another trait based on a runtime check.

The background:

I work on a library that has roughly following structure:

trait A {
    fn aa(&self) -> &str;
    fn ab(&self) -> &str;
}

struct AImpl;
impl A for AImpl { /* ... */ }

trait B {
    fn ba(&self) -> &str;
    fn bb(&self) -> &str;
}

struct BImpl;
impl B for BImpl { /* ... */ }

// and more impls for A and B

trait AorB {
    fn aa(&self) -> Option<&str>;
    fn ab(&self) -> Option<&str>;
    fn ba(&self) -> Option<&str>;
    fn bb(&self) -> Option<&str>;
}

If a type implements A then AorB returns Some(...) for the a* methods and for B respectively. &str is just a placeholder for different, more complex types.

The problem is that there are more methods which means AorB gets really messy and it would be a lot nicer if we could downcast dyn AorB to dyn A and so on. This could easily be done with a as_a(&self) -> Option<&dyn A>.

Now for the problem:

  • Semantically we need AorB and as users should be able to supply their own implementations of A and B we can not use an enum.
  • As there are a lot of traits we have many functions that are generic over those traits (sometimes with 3 and more type parameters). Given the possibility of many implementations this blows up compile time and code size.
  • The crate has various use-cases some where size matters more and some where performance is of more interest.
  • As a solution we want to offer to either use monomorphization with concrete types or use trait objects, i.e. use dyn AorB for type parameters.
  • This means AorB must be trait safe and allow to monomorphize based on a concrete type. In turn, this prevents us from using as_a(&self) -> Option<&dyn A> as it returns again a trait object which blocks monomorphization.

Has anyone an idea how this could work without returning Option from each method?

Why not this:

enum AorB<AType: A, BType: B> {
    A(AType),
    B(BType)
}

The only downside I can see is that creator of the enum must always provide both parameters, if they only use one of them.

Thank you for your suggestion.

Sadly, AorB is actually rather a AorBorCorD though which means the enum would have 4 type parameters... well that isn't really better...

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.