I'm having an error I can't understand and cannot precisely locate in the code.
Rustc points the following error ito the sabiah_server
return value (line 60):
hidden type for `impl Trait` captures lifetime that does not appear in bounds
note: hidden type `impl std::future::Future` captures lifetime smaller than the function body rustc(E0700)
Can someone explain me it better? If I understand it I shall try to contribute to this issue about a better presentation of the problem.
use crate::lib::SabiahError;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
use serde::Deserialize;
use serde_json;
use std::convert::Infallible;
use std::net::{IpAddr, SocketAddr};
mod suggest;
mod tests;
pub const DEFAULT_HOST: &str = "0.0.0.0";
pub const DEFAULT_PORT: &str = "1533";
fn make_response(s: StatusCode, body: Option<Body>) -> Response<Body> {
let body: Body = match body {
Some(data) => data,
None => s.canonical_reason().unwrap().into(),
};
Response::builder().status(s).body(body).unwrap()
}
/// Makes up a BAD_REQUEST response for errors during data ingestion.
fn ingest_err(err: SabiahError) -> Response<Body> {
make_response(StatusCode::BAD_REQUEST, Some(Body::from(err.to_string())))
}
/// Common data ingestion routine. Returns struct after data bind or, if
/// validation/deserialization fails, a response good to be sent.
async fn ingest<T: for<'de> Deserialize<'de>>(data: Request<Body>) -> Result<T, Response<Body>> {
match hyper::body::to_bytes(data).await {
Err(err) => Err(ingest_err(err.into())),
Ok(bin_data) => match serde_json::from_slice(bin_data.as_ref()) {
Err(err) => Err(ingest_err(err.into())),
Ok(params) => Ok(params),
},
}
}
/// offer hyper services for Sabiah endpoints
async fn services(musilibs: &[String], req: Request<Body>) -> Result<Response<Body>, Infallible> {
match (req.method(), req.uri().path()) {
(&Method::GET, "/health") => Ok(Response::new(Body::from("OK (under construction)"))),
(&Method::POST, "/suggestion") => Ok(suggest::suggest(musilibs, ingest(req).await).await),
_ => Ok(make_response(StatusCode::NOT_FOUND, None)),
}
}
async fn signals() {
tokio::signal::ctrl_c()
.await
.expect("failed to install http server signal handlers");
log::info!("✓ interrupt signal received")
}
pub async fn sabiah_server<'a>(
host: &str,
port: &str,
musilibs: &'static [String],
) -> Result<(), SabiahError> {
let make_svc = make_service_fn(move |_conn| async move {
Ok::<_, Infallible>(service_fn(move |req| async move {
services(musilibs, req).await
}))
});
let ip: IpAddr = host.parse().expect("Sabiah server ip invalid");
let port: u16 = port.parse().expect("Sabiah server port invalid");
let addr = SocketAddr::from((ip, port)).into();
let server = Server::try_bind(&addr)?.serve(make_svc);
log::info!(
"✓ server listening at http://{}:{} (use CTRL-C to interrupt)",
ip,
port
);
server
.with_graceful_shutdown(signals())
.await
.map_err(|e| e.into())
}