1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
use futures::future::{BoxFuture, Future}; pub struct AsyncFnPtr<Payload, Context, Result> { func: Box<dyn Fn(Payload, Context) -> BoxFuture<'static, Result> + Send + 'static>, } #[allow(clippy::new_ret_no_self)] impl<Payload, Context, Result> AsyncFnPtr<Payload, Context, Result> where Payload: 'static, { fn new<Fut, F>(f: F) -> AsyncFnPtr<Payload, Context, Fut::Output> where F: Fn(Payload, Context) -> Fut + Send + 'static, Fut: Future<Output = Result> + Send + 'static, { AsyncFnPtr { func: Box::new(move |t: Payload, ctx: Context| Box::pin(f(t, ctx))), } } pub async fn run(&self, t: Payload, ctx: Context) -> Result { (self.func)(t, ctx).await } } pub trait IntoAsyncFnPtr<Payload, Context, Result> where Payload: 'static, { fn into(self) -> AsyncFnPtr<Payload, Context, Result>; } impl<F, Payload, Context, Result, Fut> IntoAsyncFnPtr<Payload, Context, Result> for F where F: Fn(Payload, Context) -> Fut + Send + 'static, Payload: 'static, Fut: Future<Output = Result> + Send + 'static, { fn into(self) -> AsyncFnPtr<Payload, Context, Result> { AsyncFnPtr::new(self) } }