Skip to main content

modo/cron/
handler.rs

1use std::future::Future;
2
3use crate::error::Result;
4
5use super::context::{CronContext, FromCronContext};
6
7/// A type-erased async function that can be used as a cron job handler.
8///
9/// Implemented automatically for any `async fn` whose arguments all implement
10/// [`FromCronContext`]. Up to 12 handler arguments are supported. A
11/// zero-argument handler is also supported.
12///
13/// Handlers must be `Clone + Send + 'static` so the scheduler can invoke them
14/// across multiple ticks.
15///
16/// # Examples
17///
18/// ```rust,no_run
19/// use modo::cron::Meta;
20/// use modo::Result;
21///
22/// // Zero-argument handler
23/// async fn heartbeat() -> Result<()> {
24///     Ok(())
25/// }
26///
27/// // Handler that receives job metadata
28/// async fn with_meta(meta: Meta) -> Result<()> {
29///     tracing::info!(job = %meta.name, tick = %meta.tick, "tick");
30///     Ok(())
31/// }
32/// ```
33pub trait CronHandler<Args>: Clone + Send + 'static {
34    /// Invoke the handler with the given execution context.
35    fn call(self, ctx: CronContext) -> impl Future<Output = Result<()>> + Send;
36}
37
38// 0 args
39impl<F, Fut> CronHandler<()> for F
40where
41    F: FnOnce() -> Fut + Clone + Send + 'static,
42    Fut: Future<Output = Result<()>> + Send,
43{
44    async fn call(self, _ctx: CronContext) -> Result<()> {
45        (self)().await
46    }
47}
48
49macro_rules! impl_cron_handler {
50    ($($T:ident),+) => {
51        impl<F, Fut, $($T),+> CronHandler<($($T,)+)> for F
52        where
53            F: FnOnce($($T),+) -> Fut + Clone + Send + 'static,
54            Fut: Future<Output = Result<()>> + Send,
55            $($T: FromCronContext,)+
56        {
57            #[allow(non_snake_case)]
58            async fn call(self, ctx: CronContext) -> Result<()> {
59                $(let $T = $T::from_cron_context(&ctx)?;)+
60                (self)($($T),+).await
61            }
62        }
63    };
64}
65
66impl_cron_handler!(T1);
67impl_cron_handler!(T1, T2);
68impl_cron_handler!(T1, T2, T3);
69impl_cron_handler!(T1, T2, T3, T4);
70impl_cron_handler!(T1, T2, T3, T4, T5);
71impl_cron_handler!(T1, T2, T3, T4, T5, T6);
72impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7);
73impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7, T8);
74impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
75impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
76impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
77impl_cron_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);