Off the rails with a proc macro

This commit is contained in:
2024-12-06 15:13:27 +01:00
parent 6397ed0092
commit 33d96510d3
13 changed files with 494 additions and 5 deletions

1
advent_derive/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

100
advent_derive/Cargo.lock generated Normal file
View File

@@ -0,0 +1,100 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "advent_derive"
version = "0.1.0"
dependencies = [
"darling",
"quote",
"syn",
]
[[package]]
name = "darling"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"

13
advent_derive/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "advent_derive"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
syn = "2.0"
quote = "1.0"
darling = "0.20"

57
advent_derive/src/lib.rs Normal file
View File

@@ -0,0 +1,57 @@
extern crate proc_macro;
use proc_macro::{TokenStream, TokenTree};
use quote::quote;
use syn::{parse_macro_input, parse_quote, Expr, ItemStruct};
#[proc_macro_attribute]
pub fn advent_day(attrs: TokenStream, item: TokenStream, ) -> TokenStream {
let input = parse_macro_input!(item as ItemStruct);
let ident = &input.ident;
let mut parts = vec![];
for token in attrs.into_iter() {
match token {
TokenTree::Ident(ident) => parts.push(ident.to_string()),
_ => continue
}
}
let call1 = format!("{}::new()", parts[0]);
let call2 = format!("{}::new()", parts[1]);
let part1: Expr = parse_quote!(#call1);
let part2: Expr = parse_quote!(#call2);
println!("{:?} {:?}", part1, part2);
let output = quote! {
pub struct #ident {
part1: Box::<dyn AdventDayPart1>,
part2: Box::<dyn AdventDayPart2>
}
impl Day4 {
pub fn new() -> Self {
Day4 {
part1: Box::new(#part1),
part2: Box::new(#part2)
}
}
}
impl AdventDay for #ident {
fn puzzle1(&mut self) -> Result<u64, AdventError> {
self.part1.read_input()?;
self.part1.solve()
}
fn puzzle2(&mut self) -> Result<u64, AdventError> {
self.part2.read_input()?;
self.part2.solve()
}
}
};
output.into()
}