Commits vergleichen

...

3 Commits

Autor SHA1 Nachricht Datum
313c6f4e3b added a new macro include_aoc!
this is to replace the include_data! and include_example macros.
It features partitioned inputs and unified interface
2024-12-19 09:17:37 +01:00
727285020b added the example of day 5 of 2024 2024-12-19 09:16:03 +01:00
b67724378f updated docs 2024-12-19 08:02:42 +01:00
4 geänderte Dateien mit 132 neuen und 6 gelöschten Zeilen

28
examples/2024/05.txt Normale Datei
Datei anzeigen

@ -0,0 +1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

Datei anzeigen

@ -1,8 +1,8 @@
use std::fs; use std::fs::{self, read_to_string};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use syn::{parse, Result}; use syn::{parse, LitBool, Result};
use syn::{ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
spanned::Spanned, spanned::Spanned,
@ -152,3 +152,101 @@ pub fn include_example(data: TokenStream) -> TokenStream {
} }
.into() .into()
} }
#[derive(Debug, Clone, Default)]
struct NewIncludeData {
var: String,
year: String,
day: String,
example: bool,
parts: usize,
}
impl Parse for NewIncludeData {
fn parse(input: ParseStream) -> Result<Self> {
let mut v = Self::default();
v.var = if input.peek(Ident) && !input.peek(LitInt) {
get_text(input.parse::<Ident>().unwrap())?
} else {
VAR_NAME.to_string()
};
v.year = get_text(input.parse::<LitInt>()?)?;
v.day = get_text(input.parse::<Lit>()?)?;
if input.peek(LitBool) {
v.example = input.parse::<LitBool>()?.value;
}
if input.peek(LitInt) {
v.parts = input.parse::<LitInt>()?.base10_parse()?;
}
if v.parts == 0 {
v.parts = 1;
}
Ok(v)
}
}
fn fallback(input: NewIncludeData, message: String) -> TokenStream {
if input.parts != 1 {
let postfixes = (1..=input.parts).map(|i| format_ident!("{}_{}", input.var, i));
quote! {
#(
///
const #postfixes: &str = "";
)*
}
.into()
} else {
let name = format_ident!("{}", input.var);
quote! {
/// #name
const #name: &str = "";
}
.into()
}
}
/// Macro to include data and examples.
/// The First Argument(Optional) is the name/prefix for the constant,
/// The Second is the Year
/// The Third is the day/filename without the .txt at the end
/// the fourth is if its an example or not
/// and the last is the amount of parts in the file, if it is greater than 1 the first argument is treated as an Prefix.
#[proc_macro]
pub fn include_aoc(data: TokenStream) -> TokenStream {
let input = match parse::<NewIncludeData>(data) {
Ok(data) => data,
Err(error) => return error.into_compile_error().into(),
};
let mut content = Default::default();
if !input.example {
let path = format!("{}/{}/{}.txt", DATA_DIR, input.year, input.day);
match fs::exists(path.clone()) {
Ok(true) => content = read_to_string(path).unwrap(),
Ok(false) => {},
Err(error) => return fallback(input, format!("Failed to read file: {}", error)),
};
}
if content.is_empty() {
let path = format!("{}/{}/{}.txt", EXAMPLE_DIR, input.year, input.day);
content = match fs::exists(path.clone()) {
Ok(true) => read_to_string(path).unwrap(),
Ok(false) => Default::default(),
Err(error) => return fallback(input, format!("Failed to read file: {}", error)),
};
}
if input.parts != 1 {
let parts = content.splitn(input.parts, "\n\n");
let suffix = (1..=input.parts).map(|i| format_ident!("{}_{}", input.var, i));
quote! {
#(
const #suffix: &str = #parts;
)*
}
} else {
let name = format_ident!("{}", input.var);
quote! {
const #name: &str = #content;
}
}
.into()
}

Datei anzeigen

@ -4,6 +4,7 @@ use crate::predefined_const;
use super::Kartesian; use super::Kartesian;
/// implements an method that turns an Kartesian of all sizes into Coordinates
macro_rules! to_coords_impl { macro_rules! to_coords_impl {
($subtype:ident) => { ($subtype:ident) => {
impl ToCoords for Kartesian<$subtype> { impl ToCoords for Kartesian<$subtype> {
@ -63,9 +64,6 @@ to_coords_impl!(u128);
impl ToCoords for Kartesian<usize> { impl ToCoords for Kartesian<usize> {
fn to_coords(self) -> Kartesian<usize> { fn to_coords(self) -> Kartesian<usize> {
Kartesian { self
x: self.x,
y: self.y,
}
} }
} }

Datei anzeigen

@ -66,6 +66,7 @@ pub enum ExtendedOption<T> {
None, None,
} }
/// exports an alias to an value of an enum.
#[macro_export] #[macro_export]
macro_rules! enum_alias { macro_rules! enum_alias {
($enum:ident, $alias:ident, $target:ident) => { ($enum:ident, $alias:ident, $target:ident) => {
@ -78,6 +79,7 @@ macro_rules! enum_alias {
}; };
} }
/// reexports an Constant into an constant of an Trait
#[macro_export] #[macro_export]
macro_rules! predefined_const { macro_rules! predefined_const {
($trait_name:ident, $const:ident, $t:ty) => { ($trait_name:ident, $const:ident, $t:ty) => {