In a previous question I had the following code using hyper:
use std::{
convert::Infallible,
net::SocketAddr,
sync::{Arc, Mutex},
};
use hyper::{
header,
service::{make_service_fn, service_fn},
Body, Method, Request, Response, Server,
};
// I'm only using a usize here for demonstration purposes.
async fn handle(data: Arc<Mutex<usize>>, req: Request<Body>) -> Result<Response<Body>, Infallible> {
let data = *data.lock().unwrap();
Ok(Response::new(data.to_string().into()))
}
#[tokio::main]
async fn main() {
let data = Arc::new(Mutex::new(5));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_svc = make_service_fn(move |_conn| {
let data = data.clone();
async move { Ok::<_, Infallible>(service_fn(move |req| handle(data.clone(), req))) }
});
let server = Server::bind(&addr).serve(make_svc);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
In an effort to better understand what's going on, I made the following (working) changes:
let make_svc = make_service_fn(|_conn| {
let data = data.clone();
let handle = move |req| handle(data.clone(), req);
let service = service_fn(handle);
async { Ok::<_, Infallible>(service) }
});
but if I take it a step further:
let make_service = |_conn| {
let data = data.clone();
let handle = move |req| handle(data.clone(), req);
let service = service_fn(handle);
async { Ok::<_, Infallible>(service) }
};
let make_svc = make_service_fn(make_service);
I get an error that the implementation of FnOnce is not general enough. I don't understand why these two refactorings would be different. Can anyone shed some light on this?
The exact error is:
error: implementation of `FnOnce` is not general enough
--> src/main.rs:84:21
|
84 | if let Err(e) = server.await {
| ^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 AddrStream) -> impl Future<Output = [async output]>` must implement `FnOnce<(&'1 AddrStream,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 AddrStream,)>`, for some specific lifetime `'2`
Thanks