diff --git a/macros/src/lib.rs b/macros/src/lib.rs index bb25b57..598f090 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,3 +1,5 @@ +use std::fs; + use proc_macro::TokenStream; use quote::quote; use syn::{ @@ -7,6 +9,10 @@ use syn::{ }; use syn::{parse, LitInt, Result}; +const DATA_DIR: &str = "data"; +const EXAMPLE_DIR: &str = "examples"; + +#[derive(Debug, Clone)] struct IncludeData { year: String, day: String, @@ -63,20 +69,29 @@ impl Parse for IncludeData { } } -fn get_stream(dir: &str, data: Result) -> TokenStream { - match data { - Ok(id) => { - let path = format!("../../../{}/{}/{}.txt", dir, id.year, id.day); - quote! { - static DATA: &str = include_str!(#path); +fn canonicalize(dir: &str, input: Result) -> Option { + let pathname = match input { + Ok(id) => Some(format!("{}/{}/{}.txt", dir, id.year, id.day)), + Err(_) => None, + }; + if let Some(p) = pathname { + match fs::canonicalize(p.clone()) { + Ok(canon) => { + if canon.is_file() { + Some(canon.to_str().unwrap().to_string()) + } else { + println!("ERROR: {:?} is not a file", canon); + None + } + } + Err(err) => { + println!("ERROR: {} does not exist: {}", p, err); + None } } - Err(_)=> { - quote! { - static DATA: &str = ""; - } - } - }.into() + } else { + None + } } /// includes Data from Advent of code @@ -93,10 +108,33 @@ fn get_stream(dir: &str, data: Result) -> TokenStream { /// ``` #[proc_macro] pub fn include_data(data: TokenStream) -> TokenStream { - get_stream("data", parse::(data)) + let input = parse::(data); + let mut path = canonicalize(DATA_DIR, input.clone()); + if path.is_none() { + path = canonicalize(EXAMPLE_DIR, input) + } + match path { + Some(p) => quote! { + static DATA: &str = include_str!(#p); + } + .into(), + None => quote! { + static DATA: &str = ""; + } + .into(), + } } #[proc_macro] -pub fn include_example(data: TokenStream)->TokenStream { - get_stream("examples", parse::(data)) -} \ No newline at end of file +pub fn include_example(data: TokenStream) -> TokenStream { + match canonicalize(EXAMPLE_DIR, parse::(data)) { + Some(p) => quote! { + static DATA: &str = include_str!(#p); + } + .into(), + None => quote! { + static DATA: &str = ""; + } + .into(), + } +} diff --git a/src/bin/2024/01.rs b/src/bin/2024/01.rs index 8f8ab3b..2ee455e 100644 --- a/src/bin/2024/01.rs +++ b/src/bin/2024/01.rs @@ -1,5 +1,6 @@ use advent_of_code::strings::{parsenumber, splitspace}; -use adventofcode_macros::include_data; +#[allow(unused_imports)] +use adventofcode_macros::{include_data, include_example}; include_data!(2024 01);