aoc-zen-runner-macros 0.1.9

Macros for aoc-zen-runner.
Documentation
use proc_macro2::Ident;
use syn::{parse::Parse, token::Comma, Lit};

#[derive(Debug, PartialEq, Eq)]
pub struct AocMacroArgs {
    pub year_num: u32,
    pub day_num: u32,
}

impl Parse for AocMacroArgs {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let year_lit: Lit = input.parse()?;
        input.parse::<Comma>()?;
        let day_ident: Ident = input.parse()?;

        let day_part = day_ident.to_string();
        let day_part = day_part.strip_prefix("day").unwrap_or(&day_part);
        let day_part = day_part.strip_prefix("d").unwrap_or(&day_part);
        let day_num: u32 = day_part.parse().or_else(|a| {
            let msg = format!("Could not parse number from day indicator. Parsing error:\n{}", a);
            let e = syn::Error::new(day_ident.span(), msg);
            return Err(e);
        })?;

        let year_num = if let Lit::Int(li) = year_lit {
            li.base10_parse()?
        } else {
            let e = syn::Error::new(
                year_lit.span(),
                "First argument to `aoc` macro must be the puzzle's year as a number.",
            );
            return Err(e);
        };

        if day_num < 1 || day_num > 25 {
            let e = syn::Error::new(day_ident.span(), "Day number is out of range of 1-25");
            return Err(e);
        }

        Ok(AocMacroArgs { year_num, day_num })
    }
}