Jump to content

A Minimal Rust Template for Advent of Code

From JOHNWICK
Revision as of 13:13, 23 November 2025 by PC (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Every year when Advent of Code begins, I find myself repeating the same routine: copy last year’s folder, delete the old solutions, reset the inputs, and re-establish the structure. It technically works, but it’s tedious, and it makes the first day of AoC feel messier than it should. I’ve used several Rust templates over the years, but most of them fell into two extremes: either too bare-bones to stay organized for the entire AoC days, or too elaborate, with traits, macros, or abstractions that added more overhead than value. Eventually I decided to build the version I actually needed: a clean, simple workspace that handles the repetitive setup work but doesn’t impose a solving style or introduce unnecessary complexity. I just want to solve the code puzzle, learn some Rust programming best practice along the way, without resorting to advanced DevOps magic.

What I Built

The template consists of nine Rust files split across a small Cargo workspace.

Solution Library (aoc-lib)

  • lib.rs - maps years and days to solution functions
  • year2024.rs - example year module
  • year2024/day01.rs - example day solution
  • utils/mod.rs - utility exports
  • utils/input.rs - input loading and downloading
  • utils/output.rs - formatting helpers

CLI (aoc)

  • main.rs - run solutions, list days, download inputs
  • bin/new-day.rs - generates a new day’s file structure and prints instructions for updating lib.rs

Benchmarks (benches)

  • all_days.rs - Criterion benchmark suite

Why This Workspace Structure Works The workspace keeps compilation fast. Editing a single day’s file doesn’t trigger a rebuild of the whole project. Each day lives in its own module, keeping December’s growing collection of solutions organized.

The layout is reusable across years. Nothing is tied to a specific calendar, so adding a new year doesn’t require restructuring — just generate the module and register it in lib.rs.

Finally, the template avoids unnecessary abstractions. Advent of Code puzzles don’t follow a predictable structure, so traits, macros, or generic parsing layers often create more work than they solve. A straightforward, explicit project layout ends up being the most flexible approach.


Using the Template Day-to-Day Here’s the workflow you’ll follow throughout the event. git clone https://github.com/sanctusgee/advent-of-code-rust-template cd advent-of-code-rust-template cargo build export AOC_SESSION="your_session_cookie" It caches inputs locally and respects Advent of Code’s policy about not sharing puzzle inputs publicly, eg when uploading to public repo. The .gitignore blocks all .txt files in the input directory. How to Get Your AoC Session Cookie Here’s the simplest way to find it: - Log in to https://adventofcode.com- Right-click the page → Inspect (or press F12)
- Open the Network tab
- Refresh the page
- Click the first request to adventofcode.com

In the Request Headers, look for a header named Cookie
Copy the long value that begins with session=
Then export it: export AOC_SESSION="paste_the_value_here" Important: Do not share or commit this value, preferably using an ignored .env file that is referenced in .gitignore. Anyone with this cookie can access your AoC account. Start a new year Step 0: Generate the first day: cargo run - bin new-day 2025 1 The script creates the folders and files, with solution scaffold for Day 1 and shows exactly what to do:

Step 1: add to aoc-lib/src/lib.rs to register the new year. Registration is manual by design so you control how years are exposed. Example below: Press enter or click to view image in full size

Step 2: Instead of manually copying input every day, the template fetches it using your session cookie. Download the day’s puzzle input with: cargo run - bin aoc download 2025 1 Step 3: Implement and run your solution: cargo run - bin aoc run 2025 1


Work on the next day ( 2, 3, 4 …) First generate the new day’s module, file, and input directory. Example for day 2 below: cargo run - bin new-day 2025 2 // change the day value as needed Repeat steps 1, 2 and 3 from above, changing the day value to match as needed. Once you understand this workflow, the remaining features fit naturally.


Generating a New Day (Starter Scaffold)

Each new day starts with a simple, consistent starter file:
use crate::utils;
use anyhow::Result;

pub fn solve() -> Result<()> {
 let input = utils::load_input(2025, 5)?;
 
 let part1 = solve_part1(&input)?;
 let part2 = solve_part2(&input)?;
 
 println!("Day 5 / Year 2025");
 println!("Part 1: {}", part1);
 println!("Part 2: {}", part2);
 
 Ok(())
}
fn solve_part1(input: &str) -> Result<impl std::fmt::Display> {
 Ok(0)
}
fn solve_part2(input: &str) -> Result<impl std::fmt::Display> {
 Ok(0)
}

You can adjust this however you want. The only requirement is that each day exposes a solve() function with a Result<()> signature.


Benchmarks Criterion is already set up. If you want to compare approaches or measure performance, simply run cargo bench. Reports are generated at target/criterion/report/index.html.


Technical Details Core dependencies:

  • anyhow
  • clap
  • colored
  • reqwest
  • criterion

Optional dependencies (commented out so you can enable them selectively):
regex, itertools, ahash, atoi, once_cell The project passes cargo clippy with zero warnings.


Conclusion This template gives you a structured but lightweight foundation for Advent of Code. It removes repetitive setup steps, keeps the workspace organized as the month progresses, and stays flexible for any solving style. It’s simple enough to reuse every year without changes, and clear enough to adapt when needed. The full project is available here: https://github.com/sanctusgee/advent-of-code-rust-template If you try it and have suggestions, feel free to open an issue or fork it.

Read the full article here: https://medium.com/@godwin.dsg/a-minimal-rust-template-for-advent-of-code-bd5f9d0f1753