1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
extern crate proc_macro;
#[macro_use] extern crate syn;
#[macro_use] extern crate quote;

use proc_macro::TokenStream;
use syn::{parse, parse::Parser, punctuated::Punctuated, Expr, ItemFn, FnArg};

#[proc_macro_attribute]
pub fn aoc(attr: TokenStream, item: TokenStream) -> TokenStream {
    let exprs = Punctuated::<Expr, Token![,]>::parse_terminated
        .parse(attr)
        .unwrap()
        .into_iter()
        .collect::<Vec<_>>();
    let (event, day, level) = match &*exprs {
        [event, day, level] => (event, day, level),
        _ => panic!("aoc: Invalid number of parameters"),
    };
    let fun = parse::<ItemFn>(item)
        .ok().expect("aoc can only be applied to functions");
    let ident = &fun.ident;

    let out = quote! {
        fn #ident() {
            #fun
            ::aoc::cli::run(&#event.to_string(), #day, #level, #ident);
        }
    };

    out.into()
}