✨ Expand fn_builder to generic functions
This commit is contained in:
parent
36c931486d
commit
400a492311
1 changed files with 24 additions and 11 deletions
|
|
@ -15,18 +15,35 @@ pub fn html(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let fn_item = parse_macro_input!(item as ItemFn);
|
let fn_alter = parse_macro_input!(item as ItemFn);
|
||||||
let fn_alter_name = fn_item.sig.ident.to_string();
|
let fn_alter_name = fn_alter.sig.ident.to_string();
|
||||||
|
|
||||||
if !fn_alter_name.starts_with("alter_") {
|
if !fn_alter_name.starts_with("alter_") {
|
||||||
let expanded = quote_spanned! {
|
let expanded = quote_spanned! {
|
||||||
fn_item.sig.ident.span() =>
|
fn_alter.sig.ident.span() =>
|
||||||
compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method");
|
compile_error!("expected a \"pub fn alter_...() -> &mut Self\" method");
|
||||||
};
|
};
|
||||||
return expanded.into();
|
return expanded.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let args: Vec<String> = 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<String> = fn_alter
|
||||||
.sig
|
.sig
|
||||||
.inputs
|
.inputs
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -34,7 +51,7 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
.map(|arg| arg.to_token_stream().to_string())
|
.map(|arg| arg.to_token_stream().to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let param: Vec<String> = args
|
let params: Vec<String> = args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
arg.split_whitespace()
|
arg.split_whitespace()
|
||||||
|
|
@ -45,12 +62,10 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let fn_with_name = fn_alter_name.replace("alter_", "with_");
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let fn_with = parse_str::<ItemFn>(concat_string!("
|
let fn_with = parse_str::<ItemFn>(concat_string!("
|
||||||
pub fn ", fn_with_name, "(mut self, ", args.join(", "), ") -> Self {
|
pub fn ", fn_with_generics, "(mut self, ", args.join(", "), ") -> Self ", where_clause, "{
|
||||||
self.", fn_alter_name, "(", param.join(", "), ");
|
self.", fn_alter_name, "(", params.join(", "), ");
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
").as_str()).unwrap();
|
").as_str()).unwrap();
|
||||||
|
|
@ -64,8 +79,6 @@ pub fn fn_builder(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
"</p>"
|
"</p>"
|
||||||
);
|
);
|
||||||
|
|
||||||
let fn_alter = fn_item.into_token_stream();
|
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#fn_with
|
#fn_with
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue