hyper_server/
service.rs

1//! Module containing service traits.
2//! These traits are vital for handling requests and creating services within the server.
3
4use http::Response;
5use http_body::Body;
6use std::{
7    future::Future,
8    task::{Context, Poll},
9};
10use tower_service::Service;
11
12// TODO(Document the types here to disable the clippy annotation)
13
14/// An alias trait for the [`Service`] trait, specialized with required bounds for the server's service function.
15/// This trait has been sealed, ensuring it cannot be implemented by types outside of this crate.
16///
17/// It provides constraints for the body data, errors, and asynchronous behavior that fits the server's needs.
18#[allow(missing_docs)]
19pub trait SendService<Request>: send_service::Sealed<Request> {
20    type Service: Service<
21            Request,
22            Response = Response<Self::Body>,
23            Error = Self::Error,
24            Future = Self::Future,
25        > + Send
26        + 'static;
27
28    type Body: Body<Data = Self::BodyData, Error = Self::BodyError> + Send + 'static;
29    type BodyData: Send + 'static;
30    type BodyError: Into<Box<dyn std::error::Error + Send + Sync>>;
31
32    type Error: Into<Box<dyn std::error::Error + Send + Sync>>;
33    type Future: Future<Output = Result<Response<Self::Body>, Self::Error>> + Send + 'static;
34
35    /// Convert this type into a service.
36    fn into_service(self) -> Self::Service;
37}
38
39impl<T, B, Request> send_service::Sealed<Request> for T
40where
41    T: Service<Request, Response = Response<B>>,
42    T::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
43    T::Future: Send + 'static,
44    B: Body + Send + 'static,
45    B::Data: Send + 'static,
46    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
47{
48}
49
50impl<T, B, Request> SendService<Request> for T
51where
52    T: Service<Request, Response = Response<B>> + Send + 'static,
53    T::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
54    T::Future: Send + 'static,
55    B: Body + Send + 'static,
56    B::Data: Send + 'static,
57    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
58{
59    type Service = T;
60
61    type Body = B;
62    type BodyData = B::Data;
63    type BodyError = B::Error;
64
65    type Error = T::Error;
66
67    type Future = T::Future;
68
69    fn into_service(self) -> Self::Service {
70        self
71    }
72}
73
74/// A variant of the [`MakeService`] trait that accepts a `&Target` reference.
75/// This trait has been sealed, ensuring it cannot be implemented by types outside of this crate.
76/// It is specifically designed for the server's `serve` function.
77///
78/// This trait provides a mechanism to create services upon request, with the required trait bounds.
79///
80/// [`MakeService`]: https://docs.rs/tower/0.4/tower/make/trait.MakeService.html
81#[allow(missing_docs)]
82pub trait MakeServiceRef<Target, Request>: make_service_ref::Sealed<(Target, Request)> {
83    type Service: Service<
84            Request,
85            Response = Response<Self::Body>,
86            Error = Self::Error,
87            Future = Self::Future,
88        > + Send
89        + 'static;
90
91    type Body: Body<Data = Self::BodyData, Error = Self::BodyError> + Send + 'static;
92    type BodyData: Send + 'static;
93    type BodyError: Into<Box<dyn std::error::Error + Send + Sync>>;
94
95    type Error: Into<Box<dyn std::error::Error + Send + Sync>>;
96    type Future: Future<Output = Result<Response<Self::Body>, Self::Error>> + Send + 'static;
97
98    type MakeError: Into<Box<dyn std::error::Error + Send + Sync>>;
99    type MakeFuture: Future<Output = Result<Self::Service, Self::MakeError>>;
100
101    /// Polls to check if the service factory is ready to create a service.
102    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>>;
103
104    /// Creates and returns a service for the provided target.
105    fn make_service(&mut self, target: &Target) -> Self::MakeFuture;
106}
107
108impl<T, S, B, E, F, Target, Request> make_service_ref::Sealed<(Target, Request)> for T
109where
110    T: for<'a> Service<&'a Target, Response = S, Error = E, Future = F>,
111    S: Service<Request, Response = Response<B>> + Send + 'static,
112    S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
113    S::Future: Send + 'static,
114    B: Body + Send + 'static,
115    B::Data: Send + 'static,
116    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
117    E: Into<Box<dyn std::error::Error + Send + Sync>>,
118    F: Future<Output = Result<S, E>>,
119{
120}
121
122impl<T, S, B, E, F, Target, Request> MakeServiceRef<Target, Request> for T
123where
124    T: for<'a> Service<&'a Target, Response = S, Error = E, Future = F>,
125    S: Service<Request, Response = Response<B>> + Send + 'static,
126    S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
127    S::Future: Send + 'static,
128    B: Body + Send + 'static,
129    B::Data: Send + 'static,
130    B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
131    E: Into<Box<dyn std::error::Error + Send + Sync>>,
132    F: Future<Output = Result<S, E>>,
133{
134    type Service = S;
135
136    type Body = B;
137    type BodyData = B::Data;
138    type BodyError = B::Error;
139
140    type Error = S::Error;
141
142    type Future = S::Future;
143
144    type MakeError = E;
145    type MakeFuture = F;
146
147    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>> {
148        self.poll_ready(cx)
149    }
150
151    fn make_service(&mut self, target: &Target) -> Self::MakeFuture {
152        self.call(target)
153    }
154}
155
156// Sealed traits prevent external implementations of our core traits.
157// This provides future compatibility guarantees.
158mod send_service {
159    pub trait Sealed<T> {}
160}
161
162mod make_service_ref {
163    pub trait Sealed<T> {}
164}