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