From 400a49231117f83ec3198605ac630bbe36abec52 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 16 Mar 2024 21:12:03 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Expand=20fn=5Fbuilder=20to=20generi?= =?UTF-8?q?c=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helpers/pagetop-macros/src/lib.rs | 35 +++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/helpers/pagetop-macros/src/lib.rs b/helpers/pagetop-macros/src/lib.rs index cf525fa7..e3378a90 100644 --- a/helpers/pagetop-macros/src/lib.rs +++ b/helpers/pagetop-macros/src/lib.rs @@ -15,18 +15,35 @@ pub fn html(input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream { - let fn_item = parse_macro_input!(item as ItemFn); - let fn_alter_name = fn_item.sig.ident.to_string(); + let fn_alter = parse_macro_input!(item as ItemFn); + let fn_alter_name = fn_alter.sig.ident.to_string(); if !fn_alter_name.starts_with("alter_") { let expanded = quote_spanned! { - fn_item.sig.ident.span() => + fn_alter.sig.ident.span() => compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method"); }; return expanded.into(); } - let args: Vec = fn_item + let fn_with_name = fn_alter_name.replace("alter_", "with_"); + let fn_with_generics = if fn_alter.sig.generics.params.is_empty() { + fn_with_name.to_owned() + } else { + let g = &fn_alter.sig.generics; + concat_string!(fn_with_name, quote! { #g }.to_string()) + }; + + let where_clause = fn_alter + .sig + .generics + .where_clause + .as_ref() + .map_or(String::new(), |where_clause| { + concat_string!(quote! { #where_clause }.to_string(), " ") + }); + + let args: Vec = fn_alter .sig .inputs .iter() @@ -34,7 +51,7 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream { .map(|arg| arg.to_token_stream().to_string()) .collect(); - let param: Vec = args + let params: Vec = args .iter() .map(|arg| { arg.split_whitespace() @@ -45,12 +62,10 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream { }) .collect(); - let fn_with_name = fn_alter_name.replace("alter_", "with_"); - #[rustfmt::skip] let fn_with = parse_str::(concat_string!(" - pub fn ", fn_with_name, "(mut self, ", args.join(", "), ") -> Self { - self.", fn_alter_name, "(", param.join(", "), "); + pub fn ", fn_with_generics, "(mut self, ", args.join(", "), ") -> Self ", where_clause, "{ + self.", fn_alter_name, "(", params.join(", "), "); self } ").as_str()).unwrap(); @@ -64,8 +79,6 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream { "

" ); - let fn_alter = fn_item.into_token_stream(); - let expanded = quote! { #[doc(hidden)] #fn_with