I'm looking into create a simple web server api which would look something similar to this. I'm try to impl Handler for async function and async closures but running into what the type of F should be.
use async_trait::async_trait;
use std::sync::Arc;
use std::future::Future;
use std::pin::Pin;
enum Error {
SomeError
}
struct Server {
handler: Arc<dyn Handler>
}
impl Server {
pub fn new<H: Handler>(handler: H) -> Self
where
H: Into<Arc<H>>,
{
Self {
handler: handler.into(),
}
}
}
struct Context {}
impl Context {
fn write(&mut self, _s: &str) {
}
}
#[async_trait]
trait Handler : Send + Sync + 'static {
async fn run(&self, ctx: &mut Context) -> Result<(), Error>;
}
#[async_trait]
impl<Fun, Fut> Handler for Fun
where
Fun: Fn(&mut Context) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<(), Error>> + Send + 'static,
{
async fn run(&self, ctx: &mut Context) -> Result<(), Error> {
self(ctx).await?;
Ok(())
}
}
async fn helloworld(ctx: &mut Context) -> Result<(), Error> {
ctx.write("hello world async fn!!!");
Ok(())
}
fn main() {
let _server = Server::new(|ctx: &mut Context| async move {
ctx.write("hello world from closure!");
Ok(())
});
let _server2 = Server::new(helloworld);
}
error: lifetime may not live long enough
--> src/main.rs:57:51
|
57 | let _server = Server::new(|ctx: &mut Context| async move {
| _____________________________________-___________-_^
| | | |
| | | return type of closure `impl Future<Output = Result<(), Error>>` contains a lifetime `'2`
| | let's call the lifetime of this reference `'1`
58 | | ctx.write("hello world from closure!");
59 | | Ok(())
60 | | });
| |_____^ returning this value requires that `'1` must outlive `'2`
error[E0308]: mismatched types
--> src/main.rs:62:20
|
62 | let _server2 = Server::new(helloworld);
| ^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'r> <for<'r> fn(&'r mut Context) -> impl for<'r> Future<Output = Result<(), Error>> {helloworld} as FnOnce<(&'r mut Context,)>>`
found trait `for<'r> <for<'r> fn(&'r mut Context) -> impl for<'r> Future<Output = Result<(), Error>> {helloworld} as FnOnce<(&'r mut Context,)>>`
For more information about this error, try `rustc --explain E0308`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` due to 2 previous errors; 1 warning emitted