tower/util/
future_service.rs

1use std::fmt;
2use std::{
3    future::Future,
4    pin::Pin,
5    task::{Context, Poll},
6};
7use 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.
48pub fn future_service<F, S, R, E>(future: F) -> FutureService<F, S>
49where
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)]
60pub struct FutureService<F, S> {
61    state: State<F, S>,
62}
63
64impl<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.
104    pub const fn new(future: F) -> Self {
105        Self {
106            state: State::Future(future),
107        }
108    }
109}
110
111impl<F, S> fmt::Debug for FutureService<F, S>
112where
113    S: fmt::Debug,
114{
115    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)]
123enum State<F, S> {
124    Future(F),
125    Service(S),
126}
127
128impl<F, S> fmt::Debug for State<F, S>
129where
130    S: fmt::Debug,
131{
132    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
143impl<F, S, R, E> Service<R> for FutureService<F, S>
144where
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
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
165    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)]
175mod 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]
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
207        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
208            Ok(()).into()
209        }
210
211        fn call(&mut self, _req: ()) -> Self::Future {
212            ready(Ok(()))
213        }
214    }
215}