1 use std::fmt;
2 use std::{
3     future::Future,
4     pin::Pin,
5     task::{Context, Poll},
6 };
7 use tower_service::Service;
8 
9 /// Returns a new [`FutureService`] for the given future.
10 ///
11 /// A [`FutureService`] allows you to treat a future that resolves to a service as a service. This
12 /// can be useful for services that are created asynchronously.
13 ///
14 /// # Example
15 /// ```
16 /// use tower::{service_fn, Service, ServiceExt};
17 /// use tower::util::future_service;
18 /// use std::convert::Infallible;
19 ///
20 /// # fn main() {
21 /// # async {
22 /// // A future which outputs a type implementing `Service`.
23 /// let future_of_a_service = async {
24 ///     let svc = service_fn(|_req: ()| async { Ok::<_, Infallible>("ok") });
25 ///     Ok::<_, Infallible>(svc)
26 /// };
27 ///
28 /// // Wrap the future with a `FutureService`, allowing it to be used
29 /// // as a service without awaiting the future's completion:
30 /// let mut svc = future_service(Box::pin(future_of_a_service));
31 ///
32 /// // Now, when we wait for the service to become ready, it will
33 /// // drive the future to completion internally.
34 /// let svc = svc.ready().await.unwrap();
35 /// let res = svc.call(()).await.unwrap();
36 /// # };
37 /// # }
38 /// ```
39 ///
40 /// # Regarding the [`Unpin`] bound
41 ///
42 /// The [`Unpin`] bound on `F` is necessary because the future will be polled in
43 /// [`Service::poll_ready`] which doesn't have a pinned receiver (it takes `&mut self` and not `self:
44 /// Pin<&mut Self>`). So we cannot put the future into a `Pin` without requiring `Unpin`.
45 ///
46 /// This will most likely come up if you're calling `future_service` with an async block. In that
47 /// case you can use `Box::pin(async { ... })` as shown in the example.
future_service<F, S, R, E>(future: F) -> FutureService<F, S> where F: Future<Output = Result<S, E>> + Unpin, S: Service<R, Error = E>,48 pub fn future_service<F, S, R, E>(future: F) -> FutureService<F, S>
49 where
50     F: Future<Output = Result<S, E>> + Unpin,
51     S: Service<R, Error = E>,
52 {
53     FutureService::new(future)
54 }
55 
56 /// A type that implements [`Service`] for a [`Future`] that produces a [`Service`].
57 ///
58 /// See [`future_service`] for more details.
59 #[derive(Clone)]
60 pub struct FutureService<F, S> {
61     state: State<F, S>,
62 }
63 
64 impl<F, S> FutureService<F, S> {
65     /// Returns a new [`FutureService`] for the given future.
66     ///
67     /// A [`FutureService`] allows you to treat a future that resolves to a service as a service. This
68     /// can be useful for services that are created asynchronously.
69     ///
70     /// # Example
71     /// ```
72     /// use tower::{service_fn, Service, ServiceExt};
73     /// use tower::util::FutureService;
74     /// use std::convert::Infallible;
75     ///
76     /// # fn main() {
77     /// # async {
78     /// // A future which outputs a type implementing `Service`.
79     /// let future_of_a_service = async {
80     ///     let svc = service_fn(|_req: ()| async { Ok::<_, Infallible>("ok") });
81     ///     Ok::<_, Infallible>(svc)
82     /// };
83     ///
84     /// // Wrap the future with a `FutureService`, allowing it to be used
85     /// // as a service without awaiting the future's completion:
86     /// let mut svc = FutureService::new(Box::pin(future_of_a_service));
87     ///
88     /// // Now, when we wait for the service to become ready, it will
89     /// // drive the future to completion internally.
90     /// let svc = svc.ready().await.unwrap();
91     /// let res = svc.call(()).await.unwrap();
92     /// # };
93     /// # }
94     /// ```
95     ///
96     /// # Regarding the [`Unpin`] bound
97     ///
98     /// The [`Unpin`] bound on `F` is necessary because the future will be polled in
99     /// [`Service::poll_ready`] which doesn't have a pinned receiver (it takes `&mut self` and not `self:
100     /// Pin<&mut Self>`). So we cannot put the future into a `Pin` without requiring `Unpin`.
101     ///
102     /// This will most likely come up if you're calling `future_service` with an async block. In that
103     /// case you can use `Box::pin(async { ... })` as shown in the example.
new(future: F) -> Self104     pub fn new(future: F) -> Self {
105         Self {
106             state: State::Future(future),
107         }
108     }
109 }
110 
111 impl<F, S> fmt::Debug for FutureService<F, S>
112 where
113     S: fmt::Debug,
114 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result115     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116         f.debug_struct("FutureService")
117             .field("state", &format_args!("{:?}", self.state))
118             .finish()
119     }
120 }
121 
122 #[derive(Clone)]
123 enum State<F, S> {
124     Future(F),
125     Service(S),
126 }
127 
128 impl<F, S> fmt::Debug for State<F, S>
129 where
130     S: fmt::Debug,
131 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result132     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133         match self {
134             State::Future(_) => f
135                 .debug_tuple("State::Future")
136                 .field(&format_args!("<{}>", std::any::type_name::<F>()))
137                 .finish(),
138             State::Service(svc) => f.debug_tuple("State::Service").field(svc).finish(),
139         }
140     }
141 }
142 
143 impl<F, S, R, E> Service<R> for FutureService<F, S>
144 where
145     F: Future<Output = Result<S, E>> + Unpin,
146     S: Service<R, Error = E>,
147 {
148     type Response = S::Response;
149     type Error = E;
150     type Future = S::Future;
151 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>152     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
153         loop {
154             self.state = match &mut self.state {
155                 State::Future(fut) => {
156                     let fut = Pin::new(fut);
157                     let svc = futures_core::ready!(fut.poll(cx)?);
158                     State::Service(svc)
159                 }
160                 State::Service(svc) => return svc.poll_ready(cx),
161             };
162         }
163     }
164 
call(&mut self, req: R) -> Self::Future165     fn call(&mut self, req: R) -> Self::Future {
166         if let State::Service(svc) = &mut self.state {
167             svc.call(req)
168         } else {
169             panic!("FutureService::call was called before FutureService::poll_ready")
170         }
171     }
172 }
173 
174 #[cfg(test)]
175 mod tests {
176     use super::*;
177     use crate::util::{future_service, ServiceExt};
178     use crate::Service;
179     use futures::future::{ready, Ready};
180     use std::convert::Infallible;
181 
182     #[tokio::test]
pending_service_debug_impl()183     async fn pending_service_debug_impl() {
184         let mut pending_svc = future_service(ready(Ok(DebugService)));
185 
186         assert_eq!(
187             format!("{:?}", pending_svc),
188             "FutureService { state: State::Future(<futures_util::future::ready::Ready<core::result::Result<tower::util::future_service::tests::DebugService, core::convert::Infallible>>>) }"
189         );
190 
191         pending_svc.ready().await.unwrap();
192 
193         assert_eq!(
194             format!("{:?}", pending_svc),
195             "FutureService { state: State::Service(DebugService) }"
196         );
197     }
198 
199     #[derive(Debug)]
200     struct DebugService;
201 
202     impl Service<()> for DebugService {
203         type Response = ();
204         type Error = Infallible;
205         type Future = Ready<Result<Self::Response, Self::Error>>;
206 
poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>207         fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
208             Ok(()).into()
209         }
210 
call(&mut self, _req: ()) -> Self::Future211         fn call(&mut self, _req: ()) -> Self::Future {
212             ready(Ok(()))
213         }
214     }
215 }
216