1use std::future::Future;
2
3use crate::error::Result;
4
5use super::context::{FromJobContext, JobContext};
6
7pub trait JobHandler<Args>: Clone + Send + 'static {
35 fn call(self, ctx: JobContext) -> impl Future<Output = Result<()>> + Send;
42}
43
44impl<F, Fut> JobHandler<()> for F
46where
47 F: FnOnce() -> Fut + Clone + Send + 'static,
48 Fut: Future<Output = Result<()>> + Send,
49{
50 async fn call(self, _ctx: JobContext) -> Result<()> {
51 (self)().await
52 }
53}
54
55macro_rules! impl_job_handler {
56 ($($T:ident),+) => {
57 impl<F, Fut, $($T),+> JobHandler<($($T,)+)> for F
58 where
59 F: FnOnce($($T),+) -> Fut + Clone + Send + 'static,
60 Fut: Future<Output = Result<()>> + Send,
61 $($T: FromJobContext,)+
62 {
63 #[allow(non_snake_case)]
64 async fn call(self, ctx: JobContext) -> Result<()> {
65 $(let $T = $T::from_job_context(&ctx)?;)+
66 (self)($($T),+).await
67 }
68 }
69 };
70}
71
72impl_job_handler!(T1);
73impl_job_handler!(T1, T2);
74impl_job_handler!(T1, T2, T3);
75impl_job_handler!(T1, T2, T3, T4);
76impl_job_handler!(T1, T2, T3, T4, T5);
77impl_job_handler!(T1, T2, T3, T4, T5, T6);
78impl_job_handler!(T1, T2, T3, T4, T5, T6, T7);
79impl_job_handler!(T1, T2, T3, T4, T5, T6, T7, T8);
80impl_job_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
81impl_job_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
82impl_job_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
83impl_job_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);