impl<R: Clone> ItemProcessor<R, R> for DefaultProcessor {
fn process<'a>(&'a self, item: &'a R) -> R
where
DefaultProcessor: ItemProcessor<R, R>,
{
item.clone()
}
}
And when i create an instance:
let processor: &dyn ItemProcessor<R, W> = if let Some(processor) = self.processor {
processor
} else {
let test: &dyn ItemProcessor<R, R> = &DefaultProcessor{};
test
};
The compiler said: expected reference &dyn ItemProcessor<R, W>
The problem here is that you're using different Ws in the two branches of your if, so the compiler can't find a single type &dyn ItemProcessor<R, ??> for the variable processor. To make this work, you'll need to figure out how to make the second type parameter either go away or be the same in both branches. There's several approaches to do this, but they all have different tradeoffs— It's hard to give more concrete advice without more details about how ItemProcessor is used.
Consider this problem: what should your code do if R is not equal to Wandself.processor is None? That's essentially why you have a type error — your code is assuming that if self.processor is None, then R must be equal to W, but that is trying to take run-time information back to the type checking, which is not possible.
To satisfy the compiler, you will have to have a plan for what happens if R is not equal to W and self.processor is None. There might be further problems, but at a minimum you need an answer to that question.
Actually, ItemProcessor is useful only when we have to convert an item from R to W. In this case the user create an object which implements ItemProcessor trait. In this case, is Some. When we don't have to transform, the ItemProcessor is None and I want to force to use the default one "DefaultProcessor" which just as to receive an item and send it out. So in this case, it is sure R equal W and ItemProcessor is not None.
But I don't manage to force the casting R to W. I think i could serialize and deserialize with serde, but it is a poor solution
Make processor be non-optional; in the case where it would be None, instead have the caller provide DefaultProcessor. That way, the types always fit and there are no complications.
If you want to be able to write code that does not have to specify DefaultProcessor, you can do that with a builder with generic parameters — the builder method that specifies a processor also changes the types.