use crate::JobCall;
use crate::extract::{FromJobCall, FromJobCallParts};
use core::future::Future;
mod sealed {
use crate::JobCall;
pub trait Sealed {}
impl Sealed for JobCall {}
}
pub trait JobCallExt: sealed::Sealed + Sized {
fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCall<(), M> + 'static,
M: 'static;
fn extract_with_context<E, Ctx, M>(
self,
ctx: &Ctx,
) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCall<Ctx, M> + 'static,
Ctx: Send + Sync;
fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCallParts<()> + 'static;
fn extract_parts_with_context<'a, E, Ctx>(
&'a mut self,
ctx: &'a Ctx,
) -> impl Future<Output = Result<E, E::Rejection>> + Send + 'a
where
E: FromJobCallParts<Ctx> + 'static,
Ctx: Send + Sync;
}
impl JobCallExt for JobCall {
fn extract<E, M>(self) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCall<(), M> + 'static,
M: 'static,
{
self.extract_with_context(&())
}
fn extract_with_context<E, Ctx, M>(
self,
ctx: &Ctx,
) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCall<Ctx, M> + 'static,
Ctx: Send + Sync,
{
E::from_job_call(self, ctx)
}
fn extract_parts<E>(&mut self) -> impl Future<Output = Result<E, E::Rejection>> + Send
where
E: FromJobCallParts<()> + 'static,
{
self.extract_parts_with_context(&())
}
async fn extract_parts_with_context<'a, E, Ctx>(
&'a mut self,
ctx: &'a Ctx,
) -> Result<E, E::Rejection>
where
E: FromJobCallParts<Ctx> + 'static,
Ctx: Send + Sync,
{
let mut call = JobCall::default();
*call.job_id_mut() = self.job_id();
*call.metadata_mut() = core::mem::take(self.metadata_mut());
let (mut parts, ()) = call.into_parts();
let result = E::from_job_call_parts(&mut parts, ctx).await;
*self.job_id_mut() = parts.job_id;
*self.metadata_mut() = core::mem::take(&mut parts.metadata);
result
}
}