tower_spawn_ready/
make.rs

1use crate::SpawnReady;
2use futures_core::ready;
3use pin_project::pin_project;
4use std::{
5    future::Future,
6    pin::Pin,
7    task::{Context, Poll},
8};
9use tower_service::Service;
10
11/// Builds SpawnReady instances with the result of an inner Service.
12#[derive(Clone, Debug)]
13pub struct MakeSpawnReady<S> {
14    inner: S,
15}
16
17impl<S> MakeSpawnReady<S> {
18    /// Creates a new `MakeSpawnReady` wrapping `service`.
19    pub fn new(service: S) -> Self {
20        Self { inner: service }
21    }
22}
23
24/// Builds a SpawnReady with the result of an inner Future.
25#[pin_project]
26#[derive(Debug)]
27pub struct MakeFuture<F> {
28    #[pin]
29    inner: F,
30}
31
32impl<S, Target> Service<Target> for MakeSpawnReady<S>
33where
34    S: Service<Target>,
35{
36    type Response = SpawnReady<S::Response>;
37    type Error = S::Error;
38    type Future = MakeFuture<S::Future>;
39
40    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
41        self.inner.poll_ready(cx)
42    }
43
44    fn call(&mut self, target: Target) -> Self::Future {
45        MakeFuture {
46            inner: self.inner.call(target),
47        }
48    }
49}
50
51impl<F, T, E> Future for MakeFuture<F>
52where
53    F: Future<Output = Result<T, E>>,
54{
55    type Output = Result<SpawnReady<T>, E>;
56
57    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
58        let this = self.project();
59        let inner = ready!(this.inner.poll(cx))?;
60        let svc = SpawnReady::new(inner);
61        Poll::Ready(Ok(svc))
62    }
63}