I am trying to declare a trait to capture a set of implementations that convert one type to another type.
trait Convertor<In, Out>: 'static + Clone {
fn convert<'a>(self, input: In) -> Out
where
In: 'a,
Out: 'a;
}
I want the convertor itself to not hold any non static references, hence declared on 'static and also be clonable.
The method convert however need not require input be 'static, (i.e. I would like to allow taking in references as well). The only guarantee to be give is that output must be valid for at least the lifetime of input.
As the convert method consumes itself, I create a trait to jump over virtual methods over a Box like
trait ErasedConvertor<In, Out>: 'static {
fn boxed_convert<'a>(self: Box<Self>, input: In) -> Out
where
In: 'a,
Out: 'a;
fn boxed_clone(&self) -> Box<dyn ErasedConvertor<In, Out>>;
}
impl<C, In, Out> ErasedConvertor<In, Out> for C
where
C: 'static + Convertor<In, Out> + Clone,
{
fn boxed_convert<'a>(self: Box<Self>, input: In) -> Out
where
In: 'a,
Out: 'a,
{
self.convert(input)
}
fn boxed_clone(&self) -> Box<dyn ErasedConvertor<In, Out>> {
Box::new(self.clone())
}
}
Then went about declaring a boxed convertor as
struct BoxedConvertor<In, Out> {
convertor: Box<dyn ErasedConvertor<In, Out>>,
}
Now purely through the signature of BoxedConvertor<In,Out> it looks like(and is the case that) the lifetime of it should be minimum of lifetime of In and Out.
But the struct can be technically 'static as all the fields in it are 'static too.
(I want to claim dyn ErasedConvertor<In,Out> be 'static even when In and Out need not be 'static, In a sense to declare it can never hold In and Out if they are not 'static)
The below code leads to compilation error, as compiler asks for In and Out to be 'static which defeats the goal.
impl<In, Out> Convertor<In, Out> for BoxedConvertor<In, Out> {
fn convert<'a>(self, input: In) -> Out
where
In: 'a,
Out: 'a,
{
self.convertor.boxed_convert(input)
}
}
impl<In, Out> Clone for BoxedConvertor<In, Out> {
fn clone(&self) -> Self {
Self {
convertor: self.convertor.boxed_clone(),
}
}
}
Any implementation of ErasedConvertor<In,Out> can't hold non static references as the trait is super trait on 'static.
Any ways to implement something like this?