Hello, I'm very new to Rust and have just been playing around with different things.
Most of the problems I've encountered were solved by searching, but I've spent a lot of time on this one with no luck so far. I admit that it could very well be due to sorely lacking understanding about fundamentals, which is something I'm hoping to amend with this post.
I've created a playground with a reproduction of the issue. The Handler
trait actually is from the lambda_runtime Handler
trait, not something I've created myself.
In trying to implement the Handler
trait, I'm blocked by the associated type Fut
. From what I understand so far, Future
is a trait not a type, so it can't be used to specify the associated type in the implementation.
So, my question is, how should Handler
be implemented? And why is what I've been trying not working?
I would really appreciate your help!
use async_trait::async_trait;
use anyhow::Error;
use core::future::Future;
trait Handler<A, B> {
type Error;
type Fut: Future<Output = Result<B, Self::Error>>;
fn call(&self, request: A) -> Self::Fut;
}
struct WorkerRequest {
id: String,
}
struct WorkerResult {
message: String,
}
#[async_trait]
trait Worker {
async fn do_work(&self, request: WorkerRequest) -> Result<WorkerResult, Error>;
}
struct MyHandler<T: Worker> {
worker: T,
}
impl<T: Worker> MyHandler<T> {
fn new(worker: T) -> Self {
MyHandler {
worker: worker,
}
}
async fn work(&self, request: WorkerRequest) -> Result<WorkerResult, Error> {
let result = self.worker.do_work(request).await?;
Ok(result)
}
}
impl<T, F> Handler<WorkerRequest, WorkerResult> for MyHandler<T>
where
T: Worker,
F: Future<Output = Result<WorkerResult, Error>>
{
type Error = Error;
type Fut = F;
fn call(&self, request: WorkerRequest) -> Self::Fut {
self.work(request)
}
}
fn main() {
println!("This is a no-op!");
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0207]: the type parameter `F` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:41:9
|
41 | impl<T, F> Handler<WorkerRequest, WorkerResult> for MyHandler<T>
| ^ unconstrained type parameter
error: aborting due to previous error
For more information about this error, try `rustc --explain E0207`.
error: could not compile `playground`
To learn more, run the command again with --verbose.