blueprint_core/job/
future.rs

1//! Job future types.
2
3use crate::JobCall;
4use crate::JobResult;
5use crate::error::BoxError;
6use core::{future::Future, pin::Pin, task::Context};
7use futures_util::future::Map;
8use pin_project_lite::pin_project;
9use tower::Service;
10use tower::util::Oneshot;
11
12type ServiceFutureInner<F> = Map<F, fn(Option<JobResult>) -> Result<Option<JobResult>, BoxError>>;
13
14opaque_future! {
15    /// The response future for [`IntoService`](super::IntoService).
16    pub type IntoServiceFuture<F> = ServiceFutureInner<F>;
17}
18
19type LayeredFutureInner<S> = Map<
20    Oneshot<S, JobCall>,
21    fn(
22        Result<<S as Service<JobCall>>::Response, <S as Service<JobCall>>::Error>,
23    ) -> Option<JobResult>,
24>;
25
26pin_project! {
27    /// The response future for [`Layered`](super::Layered).
28    pub struct LayeredFuture<S>
29    where
30        S: Service<JobCall>,
31    {
32        #[pin]
33        inner: LayeredFutureInner<S>,
34    }
35}
36
37impl<S> LayeredFuture<S>
38where
39    S: Service<JobCall>,
40{
41    pub(super) fn new(inner: LayeredFutureInner<S>) -> Self {
42        Self { inner }
43    }
44}
45
46impl<S> Future for LayeredFuture<S>
47where
48    S: Service<JobCall>,
49{
50    type Output = Option<JobResult>;
51
52    #[inline]
53    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> core::task::Poll<Self::Output> {
54        self.project().inner.poll(cx)
55    }
56}