🎉 [pagetop-macros] Macros para facilitar la vida

This commit is contained in:
Manuel Cillero 2023-01-27 00:30:13 +01:00
parent 065fe9eaab
commit aa26389777
3 changed files with 96 additions and 0 deletions

47
pagetop-macros/src/lib.rs Normal file
View file

@ -0,0 +1,47 @@
use concat_string::concat_string;
use proc_macro::TokenStream;
use quote::{quote, quote_spanned, ToTokens};
use syn::{parse_macro_input, parse_str, ItemFn};
#[proc_macro_attribute]
pub fn fn_with(_attr: TokenStream, item: TokenStream) -> TokenStream {
let fn_item = parse_macro_input!(item as ItemFn);
let fn_name = fn_item.sig.ident.to_string();
if !fn_name.starts_with("alter_") {
let expanded = quote_spanned! {
fn_item.sig.ident.span() =>
compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method");
};
return expanded.into();
}
let args: Vec<String> = fn_item
.sig
.inputs
.iter()
.skip(1)
.map(|arg| arg.to_token_stream().to_string())
.collect();
let param: Vec<String> = args
.iter()
.map(|arg| arg.split_whitespace().next().unwrap().to_string())
.collect();
#[rustfmt::skip]
let fn_builder = parse_str::<ItemFn>(concat_string!("
pub fn ", fn_name.replace("alter_", "with_"), "(mut self, ", args.join(", "), ") -> Self {
self.", fn_name, "(", param.join(", "), ");
self
}
").as_str()).unwrap();
let fn_original = fn_item.into_token_stream();
let expanded = quote! {
#fn_builder
#fn_original
};
expanded.into()
}