Avoid repeating common set of derives

I have a lot of structs that all end up with

#[derive(Serialize, Deserialize, Default, Debug, PartialEq)]
#[serde(default)]
pub struct SomeData {
...

Is there some way to extract that into something common, so I can just do

#[my_data_struct]
pub struct SomeData {
...

or something similar?

This can indeed be done by defining your own proc-macro attribute, see this video:

1 Like

Not built in.

1 Like

Thanks!

I tried writing a proc-macro that would output the #[derive] and #[serde] blocks, but I didn’t have much luck. Is that supported, or would I need to re-implement each of those traits myself in the macro? If so, repeating a few lines seems much simpler :slight_smile:

I would try something like this:

// [dependencies]
// quote = "0.6"
// serde = { version = "1.0", features = ["derive"] }

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;

#[proc_macro_attribute]
pub fn common_derives(_args: TokenStream, input: TokenStream) -> TokenStream {
    let mut output = TokenStream::from(quote! {
        #[derive(
            serde::Serialize,
            serde::Deserialize,
            Default,
            Debug,
            PartialEq,
        )]
        #[serde(default)]
    });
    output.extend(input);
    output
}

Caller:

use soumya92::common_derives;

#[common_derives]
pub struct SomeData {...}

That works perfectly. Thanks!
I was trying to use a derive macro earlier, which is why I ran into problems (I think), since it seems derive macros can only add code.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.