Hello! I am struggling with a design issues regarding traits and generics and I have been unable to find my answer in similar threads, I am sorry if a similar problem has been solved already and I kindly ask you to link me the relative thread.
Let's suppose I have this trait, which defines whether a struct may store an error of a generic type:
trait StoreError<E> {
fn set_error(&mut self, error: E);
fn get_error(&self) -> Option<E>;
}
I define another trait that other struct which are able to extract and handle the error may implement:
trait ErrorHandler<H> {
fn handle_from(&self, handler: H);
}
I implement this last trait for a struct which prints the result of get_error():
struct ErrorPrinter {
preamble: String
}
impl<H, E> ErrorHandler<H> for ErrorPrinter
where
H: StoreError<E>,
E: std::fmt::Debug
{
fn handle_from(&self, handler: H) {
println!("{}: {:?}", self.preamble, handler.get_error());
}
}
However, this code produces the following compilation error:
error[E0207]: the type parameter `E` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:14:9
|
14 | impl<H, E> ErrorHandler<H> for ErrorPrinter
| ^ unconstrained type parameter
This error does not show up if I force ErrorPrinter to store the type E, even if it is unused.
I am convinced that this design may result ambiguous, but I still cannot imagine a case where it would. I would like ErrorPrinter to work with any type H which is able to store an error of type E, as soon as E is "Debug-gable". Is there anyway to obtain such a behaviour? Thanks in advance.
Full code: Rust Playground