I'd like to write an async function that accepts a future pointer which is then passed into async_std::task::spawn(). The problem I have is how to properly define a future type with mutable stream argument. Here's what I have:
use async_std::net::{TcpListener, TcpStream};
type TcpHandler = fn(stream: TcpStream) -> Pin<Box<dyn std::future::Future<Output = Result<(), std::io::Error>> + Send + Sync + 'static>>;
pub async fn listen(&mut self, handler: TcpHandler) -> Result<(), std::io::Error> {
let listener = TcpListener::bind("...").await?;
while let Some(stream) = listener.incoming().next().await {
let stream = stream?;
async_std::task::spawn(handler(stream));
}
Ok(())
}
The async keyword makes the function return an impl Future, which isn't a concrete type. The Pin<Box<dyn Future>> type is suitable for hand written futures and is useful for breaking recursion in async functions.
There are two ways to approach this:
You can make handle return a Pin<Box<dyn Future>>>, that way handle will match the TcpHandler type you've defined: