blueprint_core/job/
future.rs1use 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 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 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}