tower_async/make/
make_service.rs

1//! Contains [`MakeService`] which is a trait alias for a [`Service`] of [`Service`]s.
2
3use crate::sealed::Sealed;
4use std::fmt;
5use std::marker::PhantomData;
6use tower_async_service::Service;
7
8pub(crate) mod shared;
9
10/// Creates new [`Service`] values.
11///
12/// Acts as a service factory. This is useful for cases where new [`Service`]
13/// values must be produced. One case is a TCP server listener. The listener
14/// accepts new TCP streams, obtains a new [`Service`] value using the
15/// [`MakeService`] trait, and uses that new [`Service`] value to process inbound
16/// requests on that new TCP stream.
17///
18/// This is essentially a trait alias for a [`Service`] of [`Service`]s.
19pub trait MakeService<Target, Request>: Sealed<(Target, Request)> {
20    /// Responses given by the service
21    type Response;
22
23    /// Errors produced by the service
24    type Error;
25
26    /// The [`Service`] value created by this factory
27    type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
28
29    /// Errors produced while building a service.
30    type MakeError;
31
32    /// Create and return a new service value asynchronously.
33    fn make_service(
34        &self,
35        target: Target,
36    ) -> impl std::future::Future<Output = Result<Self::Service, Self::MakeError>>;
37
38    /// Consume this [`MakeService`] and convert it into a [`Service`].
39    ///
40    /// # Example
41    /// ```
42    /// use std::convert::Infallible;
43    /// use tower_async::Service;
44    /// use tower_async::make::MakeService;
45    /// use tower_async::service_fn;
46    ///
47    /// # fn main() {
48    /// # async {
49    /// // A `MakeService`
50    /// let make_service = service_fn(|make_req: ()| async {
51    ///     Ok::<_, Infallible>(service_fn(|req: String| async {
52    ///         Ok::<_, Infallible>(req)
53    ///     }))
54    /// });
55    ///
56    /// // Convert the `MakeService` into a `Service`
57    /// let mut svc = make_service.into_service();
58    ///
59    /// // Make a new service
60    /// let mut new_svc = svc.call(()).await.unwrap();
61    ///
62    /// // Call the service
63    /// let res = new_svc.call("foo".to_string()).await.unwrap();
64    /// # };
65    /// # }
66    /// ```
67    fn into_service(self) -> IntoService<Self, Request>
68    where
69        Self: Sized,
70    {
71        IntoService {
72            make: self,
73            _marker: PhantomData,
74        }
75    }
76
77    /// Convert this [`MakeService`] into a [`Service`] without consuming the original [`MakeService`].
78    ///
79    /// # Example
80    /// ```
81    /// use std::convert::Infallible;
82    /// use tower_async::Service;
83    /// use tower_async::make::MakeService;
84    /// use tower_async::service_fn;
85    ///
86    /// # fn main() {
87    /// # async {
88    /// // A `MakeService`
89    /// let mut make_service = service_fn(|make_req: ()| async {
90    ///     Ok::<_, Infallible>(service_fn(|req: String| async {
91    ///         Ok::<_, Infallible>(req)
92    ///     }))
93    /// });
94    ///
95    /// // Convert the `MakeService` into a `Service`
96    /// let mut svc = make_service.as_service();
97    ///
98    /// // Make a new service
99    /// let mut new_svc = svc.call(()).await.unwrap();
100    ///
101    /// // Call the service
102    /// let res = new_svc.call("foo".to_string()).await.unwrap();
103    ///
104    /// // The original `MakeService` is still accessible
105    /// let new_svc = make_service.make_service(()).await.unwrap();
106    /// # };
107    /// # }
108    /// ```
109    fn as_service(&self) -> AsService<Self, Request>
110    where
111        Self: Sized,
112    {
113        AsService {
114            make: self,
115            _marker: PhantomData,
116        }
117    }
118}
119
120impl<M, S, Target, Request> Sealed<(Target, Request)> for M
121where
122    M: Service<Target, Response = S>,
123    S: Service<Request>,
124{
125}
126
127impl<M, S, Target, Request> MakeService<Target, Request> for M
128where
129    M: Service<Target, Response = S>,
130    S: Service<Request>,
131{
132    type Response = S::Response;
133    type Error = S::Error;
134    type Service = S;
135    type MakeError = M::Error;
136
137    async fn make_service(&self, target: Target) -> Result<Self::Service, Self::MakeError> {
138        Service::call(self, target).await
139    }
140}
141
142/// Service returned by [`MakeService::into_service`][into].
143///
144/// See the documentation on [`into_service`][into] for details.
145///
146/// [into]: MakeService::into_service
147pub struct IntoService<M, Request> {
148    make: M,
149    _marker: PhantomData<Request>,
150}
151
152impl<M, Request> Clone for IntoService<M, Request>
153where
154    M: Clone,
155{
156    fn clone(&self) -> Self {
157        Self {
158            make: self.make.clone(),
159            _marker: PhantomData,
160        }
161    }
162}
163
164impl<M, Request> fmt::Debug for IntoService<M, Request>
165where
166    M: fmt::Debug,
167{
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        f.debug_struct("IntoService")
170            .field("make", &self.make)
171            .finish()
172    }
173}
174
175impl<M, S, Target, Request> Service<Target> for IntoService<M, Request>
176where
177    M: Service<Target, Response = S>,
178    S: Service<Request>,
179{
180    type Response = M::Response;
181    type Error = M::Error;
182
183    #[inline]
184    async fn call(&self, target: Target) -> Result<Self::Response, Self::Error> {
185        self.make.make_service(target).await
186    }
187}
188
189/// Service returned by [`MakeService::as_service`][as].
190///
191/// See the documentation on [`as_service`][as] for details.
192///
193/// [as]: MakeService::as_service
194pub struct AsService<'a, M, Request> {
195    make: &'a M,
196    _marker: PhantomData<Request>,
197}
198
199impl<M, Request> fmt::Debug for AsService<'_, M, Request>
200where
201    M: fmt::Debug,
202{
203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204        f.debug_struct("AsService")
205            .field("make", &self.make)
206            .finish()
207    }
208}
209
210impl<M, S, Target, Request> Service<Target> for AsService<'_, M, Request>
211where
212    M: Service<Target, Response = S>,
213    S: Service<Request>,
214{
215    type Response = M::Response;
216    type Error = M::Error;
217
218    #[inline]
219    async fn call(&self, target: Target) -> Result<Self::Response, Self::Error> {
220        self.make.make_service(target).await
221    }
222}