relayr_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, punctuated::Punctuated, Lit, Token, ItemFn};
4use syn::parse::Parser;
5
6#[proc_macro_attribute]
7pub fn cron(attr: TokenStream, item: TokenStream) -> TokenStream {
8    let args = Punctuated::<Lit, Token![,]>::parse_terminated
9        .parse(attr)
10        .expect("Failed to parse attribute args");
11
12    let input = parse_macro_input!(item as ItemFn);
13    let fn_name = &input.sig.ident;
14
15    let pattern = if let Some(Lit::Str(lit_str)) = args.first() {
16        lit_str.value()
17    } else {
18        panic!("Expected a string literal with a cron expression inside #[cron(\"...\")]");
19    };
20    
21    croner::Cron::new(&pattern)
22        .with_seconds_optional()
23        .parse()
24        .expect("It doesn't seem to be a valid cron expression");
25
26    let result = quote! {
27        #input
28
29        relayr::inventory::submit! {
30            relayr::Cron { pattern: #pattern, runnable: |job_id| Box::pin(#fn_name(job_id)), name: stringify!(#fn_name) }
31        }
32    };
33
34    result.into()
35}