use crate::message::{BODY_LIMIT, HyperAnswer, answered, asked};
use alux_http_direct::DirectRoute;
use bytes::Bytes;
use core::convert::Infallible;
use core::fmt::Display;
use core::future::Future;
use core::pin::Pin;
use derive_new::new as New;
use hyper::Request;
use hyper::body::Body;
use hyper::service::Service;
#[derive(Clone, New)]
pub struct HyperRoute {
surface: DirectRoute,
#[new(value = "BODY_LIMIT")]
reading: usize,
}
impl HyperRoute {
#[must_use]
pub const fn reading(mut self, bytes: usize) -> Self {
self.reading = bytes;
self
}
pub async fn answer<Sent>(&self, request: Request<Sent>) -> HyperAnswer
where
Sent: Body<Data = Bytes>,
Sent::Error: Display,
{
match asked(request, self.reading).await {
Ok(asked) => answered(self.surface.answer(asked).await),
Err(answer) => answered(answer),
}
}
}
impl<Sent> Service<Request<Sent>> for HyperRoute
where
Sent: Body<Data = Bytes> + Send + 'static,
Sent::Error: Display,
{
type Response = HyperAnswer;
type Error = Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn call(&self, request: Request<Sent>) -> Self::Future {
let served = self.clone();
Box::pin(async move { Ok(served.answer(request).await) })
}
}