Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🦀 Tip of the day 02: macro_rules! - The Dark Arts of Token Matching!

You loved macros so much yesterday, we are back for round two! While other languages just let you write functions or do blind text-replacement, Rust gives you macro_rules!, a powerful mini-language inside Rust that lets you play compiler. It’s essentially regular expressions, but for parsing your actual code!

Core Features: AST Pattern Matching: Instead of passing runtime variables, you pass literal syntax. You capture chunks of code using designators like $x:ident (for variable names) or $y:expr (for expressions). Safe Expansion: The compiler fully checks the expanded code. If your custom macro generates garbage, Rust catches it at compile time, ensuring your clever shortcuts are perfectly safe. What we actually use them for: Custom Data Structures: Rust doesn’t have a built-in dictionary literal, so we use macros to fake it! You can create a hashmap!{ “a” => 1, “b” => 2 } macro to initialize collections cleanly. Inventing Control Flow: You can literally invent new syntax. Want a Ruby-style unless keyword? A macro can turn unless!(condition, { action }) into a standard if !condition { action } behind the scenes. Mass Implementing Traits: If you have 5 different integer wrapper structs, a single macro can write the Add, Sub, and Mul traits for all of them in one go. The takeaway: macro_rules! is a superpower that lets you safely bend the laws of Rust’s syntax to eliminate boilerplate and create beautiful custom APIs.

🔇 If you moved to Rust and you miss Java, you can actually use a macro to match literal tokens and recreate that exact enterprise experience. Just do this:

macro_rules! enterprise_edition {
    // We can match the EXACT literal tokens of Java's main method!
    (public static void main(String[] args) $body:block) => {
        fn main() $body
    };
}

enterprise_edition! {
    public static void main(String[] args) {
        println!("Ah, finally... some good, verbose enterprise boilerplate!");
    }
}

…so you can wrap your elegant Rust program in that corporate nostalgia