The working handler trait uses FnMut
successfully but I cannot figure out how to use FnOnce
as an async callback.
use std::future::Future;
use futures::future::BoxFuture;
pub trait WorkingHandler: Send + Sync {
fn call(&mut self, response: u32) -> BoxFuture<'static, ()>;
}
impl<T, F> WorkingHandler for T
where
T: FnMut(u32) -> F + Send + Sync,
F: Future<Output = ()> + 'static + Send + Sync,
{
fn call(&mut self, response: u32) -> BoxFuture<'static, ()> {
Box::pin(self(response))
}
}
pub trait BrokenHandler: Send + Sync {
fn call(self, response: u32) -> BoxFuture<'static, ()>;
}
impl<T, F> BrokenHandler for T
where
T: FnOnce(u32) -> F + Send + Sync,
F: Future<Output = ()> + 'static + Send + Sync,
{
fn call(self, response: u32) -> BoxFuture<'static, ()> {
Box::pin(self(response))
}
}
#[tokio::main]
async fn main() {
let mut working_handler: Box<dyn WorkingHandler> = Box::new(move |response: u32| {
async move {
println!("hello response: {}", response);
}
});
working_handler.call(42).await;
let broken_handler: Box<dyn BrokenHandler> = Box::new(move |response: u32| {
async move {
println!("hello response: {}", response);
}
});
broken_handler.call(42).await;
}
cannot move a value of type dyn BrokenHandler: the size of dyn BrokenHandler cannot be statically determined
broken_handler.call(42).await;
^^^^^^^^^^^^^^^^^^^^^^^