1use crate::message::{BODY_LIMIT, HyperAnswer, answered, asked};
4use alux_http_direct::DirectRoute;
5use bytes::Bytes;
6use core::convert::Infallible;
7use core::fmt::Display;
8use core::future::Future;
9use core::pin::Pin;
10use derive_new::new as New;
11use hyper::Request;
12use hyper::body::Body;
13use hyper::service::Service;
14
15#[derive(Clone, New)]
20pub struct HyperRoute {
21 surface: DirectRoute,
22 #[new(value = "BODY_LIMIT")]
23 reading: usize,
24}
25
26impl HyperRoute {
27 #[must_use]
32 pub const fn reading(mut self, bytes: usize) -> Self {
33 self.reading = bytes;
34
35 self
36 }
37
38 pub async fn answer<Sent>(&self, request: Request<Sent>) -> HyperAnswer
43 where
44 Sent: Body<Data = Bytes>,
45 Sent::Error: Display,
46 {
47 match asked(request, self.reading).await {
48 Ok(asked) => answered(self.surface.answer(asked).await),
49 Err(answer) => answered(answer),
50 }
51 }
52}
53
54impl<Sent> Service<Request<Sent>> for HyperRoute
55where
56 Sent: Body<Data = Bytes> + Send + 'static,
57 Sent::Error: Display,
58{
59 type Response = HyperAnswer;
60 type Error = Infallible;
61 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
62
63 fn call(&self, request: Request<Sent>) -> Self::Future {
64 let served = self.clone();
65
66 Box::pin(async move { Ok(served.answer(request).await) })
67 }
68}