Can someone help me to complete this code to add a new function via a macro to an existing module ?
here is a purified version of the Macro code :
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{quote};
use syn::{parse_macro_input};
#[proc_macro_attribute]
pub fn my_macro(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let input = parse_macro_input!(item as syn::ItemMod);
// here, the magic code to add the new function to the module :D (which I am still looking for)
let code = quote!(
#input
);
TokenStream::from(code)
}
Should I use this method ? : input.content.insert( XXXXX )
I searched a lot but I could not find an example showing how to do it for a module with syn and quote!
Here is a simplified example of how this macro will be used :
#[my_macro()]
pub mod service {
pub fn function_a() {
}
pub fn function_b() {
}
}
the macro must add a new function to the module, to give this result :
I don't know the complexity of your proc-macro, but you could use the quote! macro to create the function and just interpolate it into the TokenStream you return:
#[proc_macro_attribute]
pub fn my_macro(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let input = parse_macro_input!(item as syn::ItemMod);
// here, the magic code to add the new function to the module :D (which I am still looking for)
let function = quote!( ... );
let code = quote!(
#input
#function
);
TokenStream::from(code)
}
Ah yes of course. Then you could probably push the function as a TokenStream onto the vector inside the content field of your ItemMod input. Something like this, I reckon:
#[proc_macro_attribute]
pub fn my_macro(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let mut input = parse_macro_input!(item as syn::ItemMod);
// here, the magic code to add the new function to the module :D (which I am still looking for)
let function = quote!( ... );
input.content.as_mut().unwrap().1.push(syn::Item::Verbatim(function));
let code = quote!(
#input
);
TokenStream::from(code)
}
I don't know that method, do you have a reference for me? It may be easier than what I did in the snippet above.