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}