I made following compilable code from your advice;
use std::future::Future;
trait SomeTrait {
fn some_async_callable() -> Box<dyn Fn(i32) -> Box<dyn Future<Output=i32>>>;
}
struct SomeStruct {}
impl SomeTrait for SomeStruct {
fn some_async_callable() -> Box<dyn Fn(i32) -> Box<dyn Future<Output=i32>>> {
Box::new(|i: i32| Box::new(async move {i+1}))
}
}
fn main() {}
So basically I wanted to hold different kind of "set of async I/O functionalities" under same container. So I made Protocol
trait which returns async closure(= closure that returns async block) that does networking, and made several structs implementing that Protocol
. Some struct is doing standard HTTPS requests, and some structs are connecting to message queues like Redis etc, under same interface.
Following code is a very rough example of my application.
async fn connect(protocol: Box<dyn Protocol>, message: String) -> String {
let closure_returns_future = protocol.send_order();
let response_message: String = closure_returns_future(&message).await;
response_message
}
However I failed to find the way to give a type hint on trait methods directly returning async closure. You cannot use impl Fn(...)
neither dyn Fn(...) -> impl Future<...>
as return type of trait method. And then I started to make a wrapper struct of dyn Fn(...) -> impl Future<...>
to make this possible.
That was my original concern. I hope you can understand my problem and my past approach.
Your code works with boxing every closure and each closure's returning async block. If I fail to find elegant way to solve my original concern, I will use this way.