use super::{FromJobCall, FromJobCallParts, JobCall};
use crate::JobResult;
use crate::job::call::Parts;
use crate::job::result::IntoJobResult;
use core::convert::Infallible;
impl<Ctx> FromJobCallParts<Ctx> for ()
where
Ctx: Send + Sync,
{
type Rejection = Infallible;
async fn from_job_call_parts(_: &mut Parts, _: &Ctx) -> Result<(), Self::Rejection> {
Ok(())
}
}
macro_rules! impl_from_job_call {
(
[$($ty:ident),*], $last:ident
) => {
#[allow(non_snake_case, unused_mut, unused_variables)]
impl<Ctx, $($ty,)* $last> FromJobCallParts<Ctx> for ($($ty,)* $last,)
where
$( $ty: FromJobCallParts<Ctx> + Send, )*
$last: FromJobCallParts<Ctx> + Send,
Ctx: Send + Sync,
{
type Rejection = Option<JobResult>;
async fn from_job_call_parts(parts: &mut Parts, ctx: &Ctx) -> Result<Self, Self::Rejection> {
$(
let $ty = $ty::from_job_call_parts(parts, ctx)
.await
.map_err(|err| err.into_job_result())?;
)*
let $last = $last::from_job_call_parts(parts, ctx)
.await
.map_err(|err| err.into_job_result())?;
Ok(($($ty,)* $last,))
}
}
#[allow(non_snake_case, unused_mut, unused_variables)]
impl<Ctx, $($ty,)* $last> FromJobCall<Ctx> for ($($ty,)* $last,)
where
$( $ty: FromJobCallParts<Ctx> + Send, )*
$last: FromJobCall<Ctx> + Send,
Ctx: Send + Sync,
{
type Rejection = Option<JobResult>;
async fn from_job_call(call: JobCall, ctx: &Ctx) -> Result<Self, Self::Rejection> {
let (mut parts, body) = call.into_parts();
$(
let $ty = $ty::from_job_call_parts(&mut parts, ctx).await.map_err(|err| err.into_job_result())?;
)*
let call = JobCall::from_parts(parts, body);
let $last = $last::from_job_call(call, ctx).await.map_err(|err| err.into_job_result())?;
Ok(($($ty,)* $last,))
}
}
};
}
all_the_tuples!(impl_from_job_call);
#[cfg(test)]
mod tests {
use bytes::Bytes;
use crate::extract::{FromJobCall, FromJobCallParts};
use crate::job::call::Parts as JobCallParts;
struct JobId;
impl<Ctx: Sync> FromJobCallParts<Ctx> for JobId {
type Rejection = ();
async fn from_job_call_parts(
_: &mut JobCallParts,
_: &Ctx,
) -> Result<Self, Self::Rejection> {
Ok(Self)
}
}
fn assert_from_job_call<M, T>()
where
T: FromJobCall<(), M>,
{
}
fn assert_from_job_call_parts<T: FromJobCallParts<()>>() {}
#[test]
fn unit() {
assert_from_job_call_parts::<()>();
assert_from_job_call::<_, ()>();
}
#[test]
fn tuple_of_one() {
assert_from_job_call_parts::<(JobId,)>();
assert_from_job_call::<_, (JobId,)>();
assert_from_job_call::<_, (Bytes,)>();
}
#[test]
fn tuple_of_two() {
assert_from_job_call_parts::<((), ())>();
assert_from_job_call::<_, ((), ())>();
assert_from_job_call::<_, (JobId, Bytes)>();
}
#[test]
fn nested_tuple() {
assert_from_job_call_parts::<(((JobId,),),)>();
assert_from_job_call::<_, ((((Bytes,),),),)>();
}
}