I have a trait like this:
trait Acceptor<B> {
fn accept(&mut self) -> B;
}
Now, it turns out that in a lot of places my code needs to use a
implementation of Acceptor
that has to be instantiated late. So,
I have lots of code like this
struct Blah {
ac: Option<SomeAcceptor<Class>>
}
impl Blah {
fn method(&mut self) {
if let Some(ac) = self.ac {
ac.accept()
}
}
}
Now this got a bit tiresome, so I thought to implement Acceptor for Option.
impl<A, B> Acceptor<B> for Option<A>
where
A: Acceptor<B>,
{
fn accept(&mut self) -> B {
match self {
Some(ac) => todo!(),
None => todo!(),
}
}
}
Now, I can write my method as:
struct Blah {
ac: Option<SomeAcceptor<Class>>
}
impl Blah {
fn method(&mut self) {
ac.accept()
}
}
This seems to work, but it fails in one instance because I have
struct Foo {
ac: Option<Box<SomeAcceptor<Class>>
}
I need the Box
to avoid a recursive data structure. So, I thought, I
need to implement Acceptor
not just for Option<A> where A:Acceptor
, but also anything that deferences to an acceptor:
use std::ops::Deref;
impl<A, B> Acceptor<B> for Option<A>
where
A: Deref<Target = Acceptor<B>>,
{
}
But this tells me that I have to use dyn
, which I presume means that
I will get dynamic dispatch for all my calls to Option<B>
including
the non Boxed ones.
Am I right? Is there something better to get this working?