adventofcode/macros/src/lib.rs

67 Zeilen
1,8 KiB
Rust

2024-12-01 16:30:48 +01:00
use proc_macro::TokenStream;
use quote::quote;
use syn::{
buffer::Cursor,
parse::{Parse, ParseStream, StepCursor},
Error,
};
use syn::{parse, LitInt, Result};
struct IncludeData {
year: String,
day: String,
}
fn get_string<'a, 'b>(cursor: StepCursor<'a, 'b>) -> Result<(String, Cursor<'a>)> {
let (lit, c) = cursor.literal().unwrap();
Ok((lit.span().source_text().unwrap(), c))
}
impl Parse for IncludeData {
fn parse(input: ParseStream) -> Result<Self> {
let mut data = IncludeData {
year: "".into(),
day: "".into(),
};
let mut look = input.lookahead1();
if !look.peek(LitInt) {
let s = input.span();
return Err(Error::new(s, format!("{} is not an valid Year", s.source_text().unwrap())));
}
data.year = input.step(get_string).expect("Wanted an string");
look = input.lookahead1();
if !look.peek(LitInt) {
let s = input.span();
return Err(Error::new(s, format!("{} is not an valid Day", s.source_text().unwrap())));
}
data.day = input.step(get_string).expect("Wanted an string");
Ok(data)
}
}
/// includes Data from Advent of code
/// ```ignore (cannot-doctest-external-file-dependency)
/// include_data!(2015 01)
///
/// fn main() {
/// print!("{DATA}");
/// }
/// ```
#[proc_macro]
pub fn include_data(data: TokenStream)->TokenStream {
let gen = match parse::<IncludeData>(data) {
Ok(data) => {
let path = format!("../../../data/{}/{}.txt", data.year, data.day);
quote! {
static DATA: &str = include_str!(#path);
}
},
Err(_) => {
quote! {
static DATA: &str = "";
}
},
};
gen.into()
}