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}