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}