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 = "year2024"))]
31pub mod year2024 {
32    pub use ::utils::puzzles_noop as puzzles;
33}
34#[cfg(feature = "year2015")]
35pub use ::year2015;
36#[cfg(feature = "year2016")]
37pub use ::year2016;
38#[cfg(feature = "year2017")]
39pub use ::year2017;
40#[cfg(feature = "year2018")]
41pub use ::year2018;
42#[cfg(feature = "year2024")]
43pub use ::year2024;
44
45/// Macro which invokes a callback macro with a list of all implemented puzzle solutions.
46///
47/// This macro chains `puzzles!` macros in the re-exported year modules. The callback macro will be
48/// called once with all the solutions, which makes it easy to generate match statements or arrays.
49///
50/// Running `cargo xtask update` will automatically update the chain of year macros.
51///
52/// # Examples
53///
54/// Simple `main` function to run all examples:
55///
56/// ```
57/// # use aoc::all_puzzles;
58/// # use utils::PuzzleExamples;
59/// # use utils::input::InputType;
60/// #
61/// macro_rules! callback {
62///     ($(
63///         $y:literal => $year:ident{$(
64///             $d:literal => $day:ident,
65///         )*}
66///     )*) => {$($(
67///         println!("{} {}", $y, $d);
68///         for (input_str, p1, p2) in aoc::$year::$day::EXAMPLES {
69///             let solution = aoc::$year::$day::new(input_str, InputType::Example).unwrap();
70///             println!("  parse({input_str}) = {solution:?}");
71///             if (p1.is_some()) { println!("  part1(...) = {}", solution.part1()); }
72///             if (p2.is_some()) { println!("  part2(...) = {}", solution.part2()); }
73///         }
74///     )*)*};
75/// }
76/// all_puzzles!(callback);
77/// ```
78///
79/// Generating a match statement:
80///
81/// ```
82/// # use aoc::all_puzzles;
83/// # use utils::date::{Day, Year};
84/// # use utils::{PuzzleExamples, Puzzle};
85/// #
86/// fn example_count(year: Year, day: Day) -> Option<usize> {
87///     macro_rules! callback {
88///         ($(
89///             $y:literal => $year:ident{$(
90///                 $d:literal => $day:ident,
91///             )*}
92///         )*) => {
93///             match (year, day) {
94///                 $($(
95///                     (aoc::$year::$day::YEAR, aoc::$year::$day::DAY) => Some(aoc::$year::$day::EXAMPLES.len()),
96///                 )*)*
97///                 _ => None,
98///             }
99///         };
100///     }
101///     all_puzzles!{callback}
102/// }
103/// ```
104#[macro_export]
105macro_rules! all_puzzles {
106    ($callback:path $(,$arg:tt)*$(,)?) => {
107        $crate::utils::puzzles_noop!{
108            [
109                // xtask update all_puzzles
110                $crate::year2015::puzzles,
111                $crate::year2016::puzzles,
112                $crate::year2017::puzzles,
113                $crate::year2018::puzzles,
114                $crate::year2024::puzzles,
115
116                $callback
117            ]
118            $($arg)*
119        }
120    };
121}