67 Zeilen
1,8 KiB
Rust
67 Zeilen
1,8 KiB
Rust
|
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()
|
||
|
}
|