beautiful proc macro
This commit is contained in:
parent
9b822cedc8
commit
f2a4de9bd9
6 changed files with 70 additions and 29 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -5,3 +5,10 @@ version = 4
|
|||
[[package]]
|
||||
name = "aoc2024"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"gendays",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gendays"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
[workspace]
|
||||
members = [ "aoc2024" ]
|
||||
members = [ "aoc2024" , "gendays"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.dependencies]
|
||||
gendays = { path = "gendays" }
|
||||
|
||||
|
|
|
|||
|
|
@ -7,3 +7,6 @@ edition = "2024"
|
|||
name = "aoc2024"
|
||||
path = "main.rs"
|
||||
|
||||
[dependencies]
|
||||
gendays = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
8
gendays/Cargo.toml
Normal 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
46
gendays/lib.rs
Normal 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()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue