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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//! # AOC Star
//!
//! `aoc-star` is a small library and CLI helper to organize and run your
//! [Advent of Code](https://adventofcode.com/) solutions.
//!
//! It provides:
//!
//! - An attribute macro `#[aoc_star::star(...)]` to register solution functions
//! for a given `day`, `part`, and optional `year`.
//! - A tiny “runner” that looks up the appropriate solution based on CLI
//! arguments and executes it, wiring up input loading and (optionally)
//! answer submission via `aoc-client`.
//!
//! ## Quick example
//!
//! Add `aoc-star` to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! aoc-star = "0.1"
//! ```
//!
//! Then in your binary crate (for example `src/bin/aoc.rs`):
//!
//! ```no_run
//! use aoc_star::star;
//!
//! #[star(day = 1, part = 1, year = 2024)]
//! fn day1_part1(input: String) -> String {
//! // Solve the puzzle here using the contents of `input`
//! input.lines().count().to_string()
//! }
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! aoc_star::run()
//! }
//! ```
//!
//! Running this binary like
//!
//! ```sh
//! cargo run -- --day 1 --part 1 --year 2024
//! ```
//!
//! will look up the registered solution for day 1, part 1, year 2024, fetch
//! the input (or read it from a file if you pass `--input-file`), and print
//! the resulting answer.
//!
//! ## Features
//!
//! - `aoc-client` (optional): enable remote input fetching and answer
//! submission using the [`aoc-client`](https://crates.io/crates/aoc-client)
//! crate. When disabled you must always provide an `--input-file`.
//! - `test-helpers`: re-exports some internals (`CommandArgument` and
//! `run_with_result`) to make integration testing easier.
//!
//!! ### `star` macro
//!
//! The `#[star(day = X, part = Y, year = Z)]` attribute macro registers
//! the annotated function as the solution for the specified day, part, and
//! optional year. The function must have the signature `fn(String) -> String`,
//! where the input `String` contains the puzzle input, and the returned
//! `String` is the answer.
//!
//! If the `year` parameter is omitted, the solution is considered
//! year-agnostic and will be used for any year that does not halve a more specific solution.
//!
//! ### CLI arguments
//!
//! The `run` function parses the following command line arguments:
//!
//! - `--day <DAY>`: The Advent of Code day (1–25).
//! - `--part <PART>`: The puzzle part (usually 1 or 2).
//! - `--year <YEAR>`: The Advent of Code year (e.g., 2024). Defaults to
//! the current year if not provided.
//! - `--input-file <FILE>`: Path to a file containing the puzzle input.
//! This argument is required if the `aoc-client` feature is not enabled.
//! - `--publish`: If provided and the `aoc-client` feature is enabled,
//! the computed answer will be submitted to Advent of Code.
//!
//! The default year is either the one on the config file or the current year.
//! The config contains the session cookie needed to fetch inputs and publish answers and
//! the default year. If not present, the config file can be created by running
//! this command with the `--setup` flag. It will be located at `$XDG_CONFIG_HOME/aoc-star/config.toml`
//! which in linux systems usually resolves to `~/.config/aoc-star/config.toml`.
//!
//! ## License
// Re-export the star macro so users can just `use aoc_star::star;`.
pub use star;
use Parser;
// This re-export is unfortunately necessary because
// the macro expansions of the `aoc_star_derive::star` macro
// need to access the `inventory` crate from the same namespace
// as this crate. There may be a better way to handle this in the future.
pub use inventory;
use craterun_with_result;
/// A registered Advent of Code solution.
///
/// Instances of this type are created by the `#[star]` attribute macro in the
/// `aoc-star-derive` crate and collected via the [`inventory`] crate. You
/// usually do not construct this type directly.
///
/// - `day`: The Advent of Code day (1–25).
/// - `part`: The part of the puzzle (1 or 2).
/// - `year`: The Advent of Code year; if `None`, the solution is considered
/// year-agnostic and will be used for any year that does not have a
/// more specific solution.
/// - `func`: The solution function, which must take the puzzle input as a
/// `String` and return the answer as a `String`.
cratecollect!;
/// Run the Advent of Code solution based on command line arguments.
///
/// This should be used in the `main` function of the binary crate that wires
/// together your solutions. It:
///
/// 1. Parses the command line using [`clap`].
/// 2. Locates the registered solution for the requested day/part/year.
/// 3. Loads the input (either from `--input-file` or, if the `aoc-client`
/// feature is enabled, remotely from Advent of Code).
/// 4. Optionally publishes the answer when `--publish` is used and
/// the `aoc-client` feature is enabled.
/// 5. Prints the resulting answer to stdout.
///
/// # Errors
///
/// Returns an error if input reading or (when enabled) communication with
/// Advent of Code fails. If no matching solution is found, this function
/// will panic.
///
/// # Examples
///
/// ```no_run
/// fn main() -> Result<(), Box<dyn std::error::Error>> {
/// aoc_star::run()
/// }
/// ```