I would like something as follows. Where my async fn my_fn(arg: &str)
takes a reference and does something with it. Note that my_fn
must be async because my real code does async stuff. See the Playground for the example.
use futures::Future;
use std::marker::PhantomData;
struct MyStruct<M, F> {
my_fn: M,
phantom: PhantomData<F>,
}
impl<M, F> MyStruct<M, F>
where
M: Fn(&str) -> F,
F: Future<Output = ()>,
{
async fn run(&mut self) {
let args = String::from("world");
(self.my_fn)(&args).await;
}
}
async fn my_fn(arg: &str) {
println!("hello {}", arg);
}
#[tokio::main]
async fn main() {
let mut s = MyStruct {
my_fn: my_fn,
phantom: PhantomData,
};
s.run().await;
}
Unfortunately I get the error:
error[E0599]: the method
run
exists for structMyStruct<for<'r> fn(&'r str) -> impl for<'r> futures::Future<Output = ()> {my_fn}, _>
, but its trait bounds were not satisfied --> src/main.rs:31:7
I see that if my_fn
takes ownership of the passed in argument such as async fn my_fn(arg: String)
instead of async fn my_fn(arg: &str)
then it works. See Playground link. Unfortunately in my real code I am not able to pass ownership to my_fn
.
use futures::Future;
use std::marker::PhantomData;
struct MyStruct<M, F> {
my_fn: M,
phantom: PhantomData<F>,
}
impl<M, F> MyStruct<M, F>
where
M: Fn(String) -> F,
F: Future<Output = ()>,
{
async fn run(&mut self) {
let args = String::from("world");
(self.my_fn)(args).await;
}
}
async fn my_fn(arg: String) {
println!("hello {}", arg);
}
#[tokio::main]
async fn main() {
let mut s = MyStruct {
my_fn: my_fn,
phantom: PhantomData,
};
s.run().await;
}
Is this an issue where I need to Pin
something or similar?