How to Write a Procedural Derive Macro in Rust

Create a library crate with the proc-macro type, define a function with the #[proc_macro_derive] attribute, and use syn and quote to generate the implementation code.

Write a procedural derive macro by creating a library crate with the proc-macro crate type, defining a function annotated with #[proc_macro_derive], and implementing the logic to parse and generate code using syn and quote.

// Cargo.toml
[lib]
proc-macro = true

[dependencies]
syn = "2.0"
quote = "1.0"

// src/lib.rs
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(MyTrait)]
pub fn my_trait_derive(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let name = &input.ident;

    let expanded = quote! {
        impl MyTrait for #name {}
    };

    TokenStream::from(expanded)
}
  1. Create a new library crate with cargo new --lib my_derive.
  2. Set proc-macro = true in the [lib] section of Cargo.toml.
  3. Add syn and quote as dependencies in Cargo.toml.
  4. Import TokenStream, quote, and syn types in src/lib.rs.
  5. Define a function annotated with #[proc_macro_derive(YourTraitName)].
  6. Parse the input token stream into a DeriveInput struct using parse_macro_input!.
  7. Extract the struct or enum name from the parsed input.
  8. Use quote! to generate the implementation code for your trait.
  9. Return the generated code as a TokenStream.