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}