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 = std::task::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 std::{
180        convert::Infallible,
181        future::{ready, Ready},
182    };
183
184    #[tokio::test]
185    async fn pending_service_debug_impl() {
186        let mut pending_svc = future_service(ready(Ok(DebugService)));
187
188        assert_eq!(
189            format!("{pending_svc:?}"),
190            "FutureService { state: State::Future(<core::future::ready::Ready<core::result::Result<tower::util::future_service::tests::DebugService, core::convert::Infallible>>>) }"
191        );
192
193        pending_svc.ready().await.unwrap();
194
195        assert_eq!(
196            format!("{pending_svc:?}"),
197            "FutureService { state: State::Service(DebugService) }"
198        );
199    }
200
201    #[derive(Debug)]
202    struct DebugService;
203
204    impl Service<()> for DebugService {
205        type Response = ();
206        type Error = Infallible;
207        type Future = Ready<Result<Self::Response, Self::Error>>;
208
209        fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
210            Ok(()).into()
211        }
212
213        fn call(&mut self, _req: ()) -> Self::Future {
214            ready(Ok(()))
215        }
216    }
217}