Macros

Rust reference - Macros

Rust by example - Macros

The Little Book of Rust Macros

#![allow(clippy::useless_vec)]

fn main() {
    // Used as an expression.
    let _x = vec![1, 2, 3];

    // Used as a statement.
    println!("Hello!");

    // Used in a pattern.
    macro_rules! pat {
        ($i:ident) => {
            Some($i)
        };
    }

    if let pat!(x) = Some(1) {
        assert_eq!(x, 1);
    }
}

// Used in a type.
macro_rules! Tuple {
    { $A:ty, $B:ty } => { ($A, $B) };
}

type _N2 = Tuple!(i32, i32);

// Used as an item.
// thread_local!(static FOO: RefCell<u32> = RefCell::new(1));

// Used as an associated item.
macro_rules! const_maker {
    ($t:ty, $v:tt) => {
        const CONST: $t = $v;
    };
}

trait T {
    const_maker! {i32, 7}
}

// Macro calls within macros.
macro_rules! _example {
    () => {
        println!("Macro call in a macro!")
    };
}

// Outer macro `example` is expanded, then inner macro `println` is
// expanded. example!();

Key crates

paste-badge (github)

Paste provides a flexible way to paste together identifiers in a macro, including using pasted identifiers to define new items.

proc-macro2-badge (github) (workshop)

proc-macro2⮳ bring proc-macro-like functionality to other contexts like build.rs and main.rs and makes procedural macros unit testable.

syn-badge (github)

Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree of Rust source code.

quote-badge

Quote provides the quote! macro for turning Rust syntax tree data structures into tokens of source code.

Tools

Cargo expand(github)

See also

proc macro workshop

watt-badge (github)