Rust Macros Designators Introduction

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we are introduced to the concept of designators in Rust macros. Designators are used to prefix the arguments of a macro and are type annotated. Some examples of designators include ident for variable/function names, expr for expressions, block for blocks of code, and pat for patterns. These designators are used within macro rules to generate code based on the provided arguments.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/DataTypesGroup -.-> rust/type_casting("`Type Conversion and Casting`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("`Traits for Operator Overloading`") subgraph Lab Skills rust/variable_declarations -.-> lab-99225{{"`Rust Macros Designators Introduction`"}} rust/type_casting -.-> lab-99225{{"`Rust Macros Designators Introduction`"}} rust/function_syntax -.-> lab-99225{{"`Rust Macros Designators Introduction`"}} rust/expressions_statements -.-> lab-99225{{"`Rust Macros Designators Introduction`"}} rust/operator_overloading -.-> lab-99225{{"`Rust Macros Designators Introduction`"}} end

Designators

The arguments of a macro are prefixed by a dollar sign $ and type annotated with a designator:

macro_rules! create_function {
    // This macro takes an argument of designator `ident` and
    // creates a function named `$func_name`.
    // The `ident` designator is used for variable/function names.
    ($func_name:ident) => {
        fn $func_name() {
            // The `stringify!` macro converts an `ident` into a string.
            println!("You called {:?}()",
                     stringify!($func_name));
        }
    };
}

// Create functions named `foo` and `bar` with the above macro.
create_function!(foo);
create_function!(bar);

macro_rules! print_result {
    // This macro takes an expression of type `expr` and prints
    // it as a string along with its result.
    // The `expr` designator is used for expressions.
    ($expression:expr) => {
        // `stringify!` will convert the expression *as it is* into a string.
        println!("{:?} = {:?}",
                 stringify!($expression),
                 $expression);
    };
}

fn main() {
    foo();
    bar();

    print_result!(1u32 + 1);

    // Recall that blocks are expressions too!
    print_result!({
        let x = 1u32;

        x * x + 2 * x - 1
    });
}

These are some of the available designators:

  • block
  • expr is used for expressions
  • ident is used for variable/function names
  • item
  • literal is used for literal constants
  • pat (pattern)
  • path
  • stmt (statement)
  • tt (token tree)
  • ty (type)
  • vis (visibility qualifier)

For a complete list, see the [Rust Reference].

Summary

Congratulations! You have completed the Designators lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like