Greetings!
I know this question already pissed everyone, but still I can't figure out what to do.
I've tried to use that:
use std::{future::Future, pin::Pin};
struct Callback<A, B> {
cb: Box<dyn for<'a> Fn(&'a A, B) -> Pin<Box<dyn Future<Output = ()> + 'a>>>,
}
impl<A, B> Callback<A, B> {
fn new<F, Fut>(callback: F) -> Self
where
F: Fn(&A, B) -> Fut + 'static,
for<'any> Fut: Future<Output = ()> + 'any,
{
Self {
cb: Box::new(move |a, b| Box::pin(callback(a, b))),
}
}
async fn call(&self, a: &A, b: B) {
(self.cb)(a, b).await
}
}
async fn concat(name: &String, id: usize) {
println!("{name}{id}");
}
fn main() {
let _cb = Callback::new(|name, id| concat(name, id));
}
And obviously got lifetime may not live long enough
error.
Of course, I can ask user to return Box<Pin<T>>
directly:
<...>
fn new<F>(callback: F) -> Self
where
for<'a> F: Fn(&'a A, B) -> Pin<Box<dyn Future<Output = ()> + 'a>> + 'a,
{
Self {
cb: Box::new(move |a, b| callback(a, b)),
}
}
<...>
let _cb = Callback::new(|name, id| Box::pin(concat(name, id)));
but this is very inconvenient for user which will use my library.
So, any way to win battle with rust life-bound checker? Maybe some GAT
magic?