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