Struct FutureService

pub struct FutureService<F, S> { /* private fields */ }

A type that implements Service for a Future that produces a Service.

See future_service for more details.

Implementations

impl<F, S> FutureService<F, S>

const fn new(future: F) -> Self

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::FutureService;
use std::convert::Infallible;

# fn main() {
# async {
// 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 = FutureService::new(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.

Trait Implementations

impl<F, S> Debug for FutureService<F, S> where S: Debug,

fn fmt(&self, f: &mut Formatter<'_>) -> Result

impl<F, S, R, E> Service<R> for FutureService<F, S> where F: Future<Output = Result<S, E>> + Unpin, S: Service<R, Error = E>,

type Response = <S as Service<R>>::Response;
type Error = E;
type Future = <S as Service<R>>::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
fn call(&mut self, req: R) -> Self::Future

impl<F: Clone, S: Clone> Clone for FutureService<F, S>

fn clone(&self) -> FutureService<F, S>

Auto Trait Implementations

impl<F, S> Freeze for FutureService<F, S> where State<F, S>: Freeze,

impl<F, S> RefUnwindSafe for FutureService<F, S> where State<F, S>: RefUnwindSafe,

impl<F, S> Send for FutureService<F, S> where State<F, S>: Send,

impl<F, S> Sync for FutureService<F, S> where State<F, S>: Sync,

impl<F, S> Unpin for FutureService<F, S> where State<F, S>: Unpin,

impl<F, S> UnsafeUnpin for FutureService<F, S> where State<F, S>: UnsafeUnpin,

impl<F, S> UnwindSafe for FutureService<F, S> where State<F, S>: UnwindSafe,

Blanket Implementations

impl<C, Target> MakeConnection<Target> for FutureService<F, S> where C: Service<Target>, <C as Service<Target>>::Response: AsyncRead + AsyncWrite,

type Connection = <C as Service<Target>>::Response;
type Error = <C as Service<Target>>::Error;
type Future = <C as Service<Target>>::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), <C as MakeConnection<Target>>::Error>>
fn make_connection(&mut self, target: Target) -> <C as MakeConnection<Target>>::Future

impl<M, S, Target, Request> MakeService<Target, Request> for FutureService<F, S> where M: Service<Target, Response = S>, S: Service<Request>,

type Response = <S as Service<Request>>::Response;
type Error = <S as Service<Request>>::Error;
type Service = S;
type MakeError = <M as Service<Target>>::Error;
type Future = <M as Service<Target>>::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), <M as MakeService<Target, Request>>::MakeError>>
fn make_service(&mut self, target: Target) -> <M as MakeService<Target, Request>>::Future

impl<T> Any for FutureService<F, S> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for FutureService<F, S> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for FutureService<F, S> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for FutureService<F, S> where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for FutureService<F, S>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> Instrument for FutureService<F, S>

impl<T> ToOwned for FutureService<F, S> where T: Clone,

type Owned = T;
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)

impl<T> WithSubscriber for FutureService<F, S>

impl<T, Request> ServiceExt<Request> for FutureService<F, S> where T: Service<Request> + ?Sized,

impl<T, U> Into<U> for FutureService<F, S> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for FutureService<F, S> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for FutureService<F, S> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>