use super::SpawnReady; use futures_core::ready; use pin_project_lite::pin_project; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use tower_service::Service; /// Builds [`SpawnReady`] instances with the result of an inner [`Service`]. #[derive(Clone, Debug)] pub struct MakeSpawnReady { inner: S, } impl MakeSpawnReady { /// Creates a new [`MakeSpawnReady`] wrapping `service`. pub fn new(service: S) -> Self { Self { inner: service } } } pin_project! { /// Builds a [`SpawnReady`] with the result of an inner [`Future`]. #[derive(Debug)] pub struct MakeFuture { #[pin] inner: F, } } impl Service for MakeSpawnReady where S: Service, { type Response = SpawnReady; type Error = S::Error; type Future = MakeFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx) } fn call(&mut self, target: Target) -> Self::Future { MakeFuture { inner: self.inner.call(target), } } } impl Future for MakeFuture where F: Future>, { type Output = Result, E>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); let inner = ready!(this.inner.poll(cx))?; let svc = SpawnReady::new(inner); Poll::Ready(Ok(svc)) } }