aoc_star_derive/
lib.rs

1//! # aoc-star-derive
2//!
3//! Procedural macro to define Advent of Code solution functions. This crate
4//! should never be used directly, but rather through the `aoc-star` crate.
5//!
6//!
7//! The `star` macro allows you to annotate functions as solutions for specific days and parts of Advent of Code challenges.
8//!
9//! ## Example
10//! ```ignore
11//! use aoc_star_derive::star;
12//!
13//! #[star(day = 1, part = 1, year = 2024)]
14//! fn solve_day1_part1(input: String) -> String {
15//!   // solution code here
16//!   "solution".to_string()
17//!   }
18//!
19//! ```
20
21mod args;
22
23use proc_macro::TokenStream;
24use quote::quote;
25use syn::{ItemFn, parse_macro_input};
26
27use crate::args::AocArgs;
28
29/// Attribute macro to mark a function as an Advent of Code solution
30/// # Example
31/// ```ignore
32/// use aoc_star_derive::star;
33///
34/// #[star(day = 1, part = 1, year = 2024)]
35/// fn solve_day1_part1(input: String) -> String {
36///    // solution code here
37///    "solution".to_string()
38///    }
39///
40/// #[star(day = 1, part = 2, year = 2024)]
41/// fn solve_day1_part2(input: String) -> String {
42///   // solution code here
43///   "solution".to_string()
44///   }
45///
46/// #[star(day = 2, part = 1)]
47/// fn solve_day2_part1(input: String) -> String {
48///  // solution code here
49///  "solution".to_string()
50///  }
51/// ```
52#[proc_macro_attribute]
53pub fn star(attr: TokenStream, item: TokenStream) -> TokenStream {
54    let args = parse_macro_input!(attr as AocArgs);
55    let input_fn = parse_macro_input!(item as ItemFn);
56
57    let fn_name = &input_fn.sig.ident;
58    let day = args.day;
59    let part = args.part;
60    let year = match args.year {
61        Some(y) => quote! { Some(#y) },
62        None => quote! { None },
63    };
64
65    let expanded = quote! {
66        #input_fn
67
68        aoc_star::inventory::submit! {
69            aoc_star::AocEntry {
70                day: #day,
71                part: #part,
72                year: #year,
73                func: #fn_name,
74            }
75        }
76    };
77
78    expanded.into()
79}