I am trying to create a trait to accept some sort of callback API but I am running into a problem that Rust can't infer the types when I tried to use a closure implementation of the trait.
Just to illustrate, the following code works fine:
fn run<H, T, E>(handler: H) -> Result<T, E>
where
H: Fn(String) -> Result<T, E>,
{
handler("10".to_owned())
}
fn main() {
run(|n| n.parse::<u8>());
}
But when I try to create a trait instead of using a function on the signature, Rust cannot infer the argument type anymore:
trait Handler<T, E> {
fn handle(&self, input: String) -> Result<T, E>;
}
impl<F, T, E> Handler<T, E> for F
where
F: Fn(String) -> Result<T, E>,
{
fn handle(&self, input: String) -> Result<T, E> {
self(input)
}
}
fn run<H, T, E>(handler: H) -> Result<T, E>
where
H: Handler<T, E>,
{
handler.handle("10".to_owned())
}
fn main() {
run(|n| n.parse::<u8>());
}
The compiler returns the following error:
error[E0282]: type annotations needed
--> src/main.rs:22:10
|
22 | run(|n| n.parse::<u8>());
| ^ consider giving this closure parameter a type
|
= note: type must be known at this point
If I give the n
parameter a explicit type (run(|n: String| ...
), then everything works, but I would like to know if is there some workaround for this inferece to work.
Edit: simplified a bit the examples