hyper/service/
http.rs

1use std::error::Error as StdError;
2use std::future::Future;
3
4use crate::body::Body;
5use crate::service::service::Service;
6use crate::{Request, Response};
7
8/// An asynchronous function from [`Request`] to [`Response`].
9///
10/// This is a *sealed* trait, meaning that it can not be implemented directly. Rather, it is an
11/// alias for [`Service`]s that accept a [`Request`] and return a [`Future`] that resolves to a
12/// [`Response`]. External callers should implement [`Service`] instead.
13///
14/// Rather than being generic over the request and response, this trait is generic across the
15/// request [`Body`] and response [`Body`].
16///
17/// See the crate-level [`service`][crate::service] documentation for more information.
18///
19/// See [`Service`] for more information.
20pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
21    /// The [`Body`] body of the [`Response`].
22    type ResBody: Body;
23
24    /// The error type that can occur within this [`Service`].
25    ///
26    /// Note: Returning an `Error` to a hyper server, the behavior depends on the protocol. In
27    /// most cases, hyper will cause the connection to be abruptly aborted. In most cases, it is
28    /// better to return a `Response` with a 4xx or 5xx status code.
29    ///
30    /// See [`Service::Error`] for more information.
31    type Error: Into<Box<dyn StdError + Send + Sync>>;
32
33    /// The [`Future`] returned by this [`Service`].
34    type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
35
36    #[doc(hidden)]
37    fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
38}
39
40impl<T, B1, B2> HttpService<B1> for T
41where
42    T: Service<Request<B1>, Response = Response<B2>>,
43    B2: Body,
44    T::Error: Into<Box<dyn StdError + Send + Sync>>,
45{
46    type ResBody = B2;
47
48    type Error = T::Error;
49    type Future = T::Future;
50
51    fn call(&mut self, req: Request<B1>) -> Self::Future {
52        Service::call(self, req)
53    }
54}
55
56impl<T, B1, B2> sealed::Sealed<B1> for T
57where
58    T: Service<Request<B1>, Response = Response<B2>>,
59    B2: Body,
60{
61}
62
63mod sealed {
64    pub trait Sealed<T> {}
65}