beautiful proc macro

This commit is contained in:
Rakarake 2025-11-30 18:57:32 +01:00
parent 9b822cedc8
commit f2a4de9bd9
6 changed files with 70 additions and 29 deletions

7
Cargo.lock generated
View file

@ -5,3 +5,10 @@ version = 4
[[package]]
name = "aoc2024"
version = "0.1.0"
dependencies = [
"gendays",
]
[[package]]
name = "gendays"
version = "0.1.0"

View file

@ -1,3 +1,7 @@
[workspace]
members = [ "aoc2024" ]
members = [ "aoc2024" , "gendays"]
resolver = "3"
[workspace.dependencies]
gendays = { path = "gendays" }

View file

@ -7,3 +7,6 @@ edition = "2024"
name = "aoc2024"
path = "main.rs"
[dependencies]
gendays = { workspace = true }

View file

@ -1,28 +1 @@
mod day1;
mod day2;
fn main() {
// part 1 or 2
let day = std::env::args().nth(1).expect("needs to specify day for first argument");
let part = std::env::args().nth(2).expect("needs to specify 1 or 2 for second argument");
if day == "day1" {
if part == "1" {
println!("{}", day1::part1());
} else if part == "2" {
println!("{}", day1::part2());
} else {
panic!("expecting 1 or 2 for argument 2")
}
}
if day == "day2" {
if part == "1" {
println!("{}", day2::part1());
} else if part == "2" {
println!("{}", day2::part2());
} else {
panic!("expecting 1 or 2 for argument 2")
}
}
}
gendays::gen_days![aoc2024];

8
gendays/Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "gendays"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
path = "lib.rs"

46
gendays/lib.rs Normal file
View file

@ -0,0 +1,46 @@
use std::fs;
use proc_macro::TokenStream;
#[proc_macro]
pub fn gen_days(item: TokenStream) -> TokenStream {
let path = format!("{item}");
let mut days_in_dir: Vec<String> = Vec::new();
for entry in fs::read_dir(&path).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if let Some(file_stem) = path.file_stem() {
let (day_prefix, day_number) = file_stem.to_str().unwrap().split_at(3);
if day_prefix == "day" {
// do template stuff for this day
days_in_dir.push(day_number.to_string());
}
}
}
let mut module_imports = String::new();
let mut day_checks = String::new();
for day in days_in_dir {
module_imports += &format!("mod day{day};\n");
day_checks += &format!("
if day == \"day{day}\" {{
if part == \"1\" {{
println!(\"{{}}\", day{day}::part1());
}} else if part == \"2\" {{
println!(\"{{}}\", day{day}::part2());
}} else {{
panic!(\"expecting 1 or 2 for argument 2\")
}}
}}
");
}
format!("
{module_imports}
fn main() {{
let day = std::env::args().nth(1).expect(\"needs to specify day for first argument\");
let part = std::env::args().nth(2).expect(\"needs to specify 1 or 2 for second argument\");
{day_checks}
}}
").parse().unwrap()
}