Skip to main content

aoc/
years.rs

1//! Implementation for [`all_puzzles!`](crate::all_puzzles!).
2//!
3//! Each of the year crates is re-exported below if the corresponding feature is enabled, or a
4//! placeholder crate with the [`utils::puzzles_noop!`] no-op `puzzles!` macro if it is not.
5//! The `puzzles!` macros are then chained together by [`all_puzzles!`](crate::all_puzzles!).
6//!
7//! This main advantage of this approach over passing `#[cfg(feature = ?)]` attributes to the
8//! callback is that it prevents disabled years from being expanded at all, which should speed up
9//! compilation.
10//!
11//! Running `cargo xtask update` will automatically update the list of re-exports.
12
13// xtask update re-exports
14#[cfg(not(feature = "year2015"))]
15pub mod year2015 {
16    pub use ::utils::puzzles_noop as puzzles;
17}
18#[cfg(not(feature = "year2016"))]
19pub mod year2016 {
20    pub use ::utils::puzzles_noop as puzzles;
21}
22#[cfg(not(feature = "year2017"))]
23pub mod year2017 {
24    pub use ::utils::puzzles_noop as puzzles;
25}
26#[cfg(not(feature = "year2018"))]
27pub mod year2018 {
28    pub use ::utils::puzzles_noop as puzzles;
29}
30#[cfg(not(feature = "year2019"))]
31pub mod year2019 {
32    pub use ::utils::puzzles_noop as puzzles;
33}
34#[cfg(not(feature = "year2020"))]
35pub mod year2020 {
36    pub use ::utils::puzzles_noop as puzzles;
37}
38#[cfg(not(feature = "year2024"))]
39pub mod year2024 {
40    pub use ::utils::puzzles_noop as puzzles;
41}
42#[cfg(not(feature = "year2025"))]
43pub mod year2025 {
44    pub use ::utils::puzzles_noop as puzzles;
45}
46#[cfg(feature = "year2015")]
47pub use ::year2015;
48#[cfg(feature = "year2016")]
49pub use ::year2016;
50#[cfg(feature = "year2017")]
51pub use ::year2017;
52#[cfg(feature = "year2018")]
53pub use ::year2018;
54#[cfg(feature = "year2019")]
55pub use ::year2019;
56#[cfg(feature = "year2020")]
57pub use ::year2020;
58#[cfg(feature = "year2024")]
59pub use ::year2024;
60#[cfg(feature = "year2025")]
61pub use ::year2025;
62
63/// Macro which invokes a callback macro with a list of all implemented puzzle solutions.
64///
65/// This macro chains `puzzles!` macros in the re-exported year modules. The callback macro will be
66/// called once with all the solutions, which makes it easy to generate match statements or arrays.
67///
68/// Running `cargo xtask update` will automatically update the chain of year macros.
69///
70/// # Examples
71///
72/// Simple `main` function to run all examples:
73///
74/// ```
75/// # use aoc::all_puzzles;
76/// # use utils::PuzzleExamples;
77/// # use utils::input::InputType;
78/// #
79/// macro_rules! callback {
80///     ($(
81///         $y:literal => $year:ident{$(
82///             $d:literal => $day:ident,
83///         )*}
84///     )*) => {$($(
85///         println!("{} {}", $y, $d);
86///         for (input_str, p1, p2) in aoc::$year::$day::EXAMPLES {
87///             let solution = aoc::$year::$day::new(input_str, InputType::Example).unwrap();
88///             println!("  parse({input_str}) = {solution:?}");
89///             if (p1.is_some()) { println!("  part1(...) = {}", solution.part1()); }
90///             if (p2.is_some()) { println!("  part2(...) = {}", solution.part2()); }
91///         }
92///     )*)*};
93/// }
94/// all_puzzles!(callback);
95/// ```
96///
97/// Generating a match statement:
98///
99/// ```
100/// # use aoc::all_puzzles;
101/// # use utils::date::Date;
102/// # use utils::{PuzzleExamples, PuzzleDate};
103/// #
104/// fn example_count(date: Date) -> Option<usize> {
105///     macro_rules! callback {
106///         ($(
107///             $y:literal => $year:ident{$(
108///                 $d:literal => $day:ident,
109///             )*}
110///         )*) => {
111///             match date {
112///                 $($(
113///                     aoc::$year::$day::DATE => Some(aoc::$year::$day::EXAMPLES.len()),
114///                 )*)*
115///                 _ => None,
116///             }
117///         };
118///     }
119///     all_puzzles!{callback}
120/// }
121/// ```
122#[macro_export]
123macro_rules! all_puzzles {
124    ($callback:path $(,$arg:tt)*$(,)?) => {
125        $crate::utils::puzzles_noop!{
126            [
127                // xtask update all_puzzles
128                $crate::year2015::puzzles,
129                $crate::year2016::puzzles,
130                $crate::year2017::puzzles,
131                $crate::year2018::puzzles,
132                $crate::year2019::puzzles,
133                $crate::year2020::puzzles,
134                $crate::year2024::puzzles,
135                $crate::year2025::puzzles,
136
137                $callback
138            ]
139            $($arg)*
140        }
141    };
142}