tower::util

Function future_service

source
pub fn future_service<F, S, R, E>(future: F) -> FutureService<F, S>
where F: Future<Output = Result<S, E>> + Unpin, S: Service<R, Error = E>,
Expand description

Returns a new FutureService for the given future.

A FutureService allows you to treat a future that resolves to a service as a service. This can be useful for services that are created asynchronously.

§Example

use tower::{service_fn, Service, ServiceExt};
use tower::util::future_service;
use std::convert::Infallible;

// A future which outputs a type implementing `Service`.
let future_of_a_service = async {
    let svc = service_fn(|_req: ()| async { Ok::<_, Infallible>("ok") });
    Ok::<_, Infallible>(svc)
};

// Wrap the future with a `FutureService`, allowing it to be used
// as a service without awaiting the future's completion:
let mut svc = future_service(Box::pin(future_of_a_service));

// Now, when we wait for the service to become ready, it will
// drive the future to completion internally.
let svc = svc.ready().await.unwrap();
let res = svc.call(()).await.unwrap();

§Regarding the Unpin bound

The Unpin bound on F is necessary because the future will be polled in Service::poll_ready which doesn’t have a pinned receiver (it takes &mut self and not self: Pin<&mut Self>). So we cannot put the future into a Pin without requiring Unpin.

This will most likely come up if you’re calling future_service with an async block. In that case you can use Box::pin(async { ... }) as shown in the example.