Generated Macros

Relevant source files

This page documents the iteration macros automatically generated by the TupleForEach derive macro. These macros provide a convenient way to iterate over tuple struct fields at compile time with type safety.

For information about the derive macro itself, see TupleForEach Derive Macro. For the generated methods (len() and is_empty()), see Generated Methods.

Overview

When you apply #[derive(TupleForEach)] to a tuple struct, the macro generates two types of iteration macros:

Macro TypePurposeNaming Pattern
*_for_each!Iterate over fields{snake_case_name}_for_each!
*_enumerate!Iterate with field indices{snake_case_name}_enumerate!

Each macro type supports both immutable and mutable variants, allowing you to read from or modify tuple fields during iteration.

Macro Name Generation

flowchart TD
PascalCase["PascalCase Struct Namee.g., 'MyTuple'"]
pascal_to_snake["pascal_to_snake()Function"]
SnakeCase["snake_case Namee.g., 'my_tuple'"]
ForEach["my_tuple_for_each!Macro"]
Enumerate["my_tuple_enumerate!Macro"]

PascalCase --> pascal_to_snake
SnakeCase --> Enumerate
SnakeCase --> ForEach
pascal_to_snake --> SnakeCase

Sources: src/lib.rs(L124 - L133)  src/lib.rs(L60 - L62) 

For Each Macros

The *_for_each! macros iterate over tuple fields sequentially, providing access to each field value.

Syntax

{name}_for_each!(field_var in tuple_instance {
    // code block using field_var
});

{name}_for_each!(field_var in mut tuple_instance {
    // code block with mutable access to field_var  
});

Generated Implementation

Macro Structure and Field Access Pattern

flowchart TD
MacroCall["macro_for_each!(item in tuple { code })"]
ImmutablePath["Immutable Variant"]
MutablePath["macro_for_each!(item in mut tuple { code })"]
ImmutableExpansion["{ let $item = &$tuple.0; $code }{ let $item = &$tuple.1; $code }{ let $item = &$tuple.2; $code }"]
MutableExpansion["{ let $item = &mut $tuple.0; $code }{ let $item = &mut $tuple.1; $code }{ let $item = &mut $tuple.2; $code }"]

ImmutablePath --> ImmutableExpansion
MacroCall --> ImmutablePath
MacroCall --> MutablePath
MutablePath --> MutableExpansion

The macro generates sequential code blocks for each tuple field, where:

  • $item becomes the field variable name you specify
  • $tuple becomes the tuple instance name you provide
  • $code becomes your code block
  • Field access uses numeric indices (.0, .1, .2, etc.)

Sources: src/lib.rs(L102 - L109)  src/lib.rs(L71 - L72) 

Usage Examples

From the test suite, here are practical examples:

// Immutable iteration over Pair(A, B)
pair_for_each!(x in t {
    println!("for_each {}: {}", i, x.foo());
    x.bar();
    i += 1;
});

// Mutable iteration over Tuple(A, B, C)  
tuple_for_each!(x in mut t {
    println!("for_each_mut {}: {}", i, x.foo());
    x.bar_mut();
    i += 1;
});

Sources: tests/test_tuple_for_each.rs(L56 - L61)  tests/test_tuple_for_each.rs(L70 - L75) 

Enumerate Macros

The *_enumerate! macros provide both field index and field value during iteration, similar to iterator enumerate functionality.

Syntax

{name}_enumerate!((index_var, field_var) in tuple_instance {
    // code block using index_var and field_var
});

{name}_enumerate!((index_var, field_var) in mut tuple_instance {
    // code block with mutable access to field_var
});

Generated Implementation

Enumerate Macro Expansion Pattern

flowchart TD
EnumCall["macro_enumerate!((idx, item) in tuple { code })"]
ImmEnum["Immutable Enumerate"]
MutEnum["Mutable Enumerate"]
ImmEnumExp["{ let $idx = 0; let $item = &$tuple.0; $code }{ let $idx = 1; let $item = &$tuple.1; $code }{ let $idx = 2; let $item = &$tuple.2; $code }"]
MutEnumExp["{ let $idx = 0; let $item = &mut $tuple.0; $code }{ let $idx = 1; let $item = &mut $tuple.1; $code }{ let $idx = 2; let $item = &mut $tuple.2; $code }"]

EnumCall --> ImmEnum
EnumCall --> MutEnum
ImmEnum --> ImmEnumExp
MutEnum --> MutEnumExp

The enumerate macros generate code blocks that provide:

  • $idx - the field index as a literal value (0, 1, 2, etc.)
  • $item - reference to the field value (immutable or mutable)
  • Sequential execution for each tuple field

Sources: src/lib.rs(L113 - L120)  src/lib.rs(L73 - L82) 

Usage Examples

// Immutable enumeration over Tuple(A, B, C)
tuple_enumerate!((i, x) in t {
    println!("enumerate {}: {}", i, x.foo());
    x.bar();
    assert_eq!(i, real_idx);
    real_idx += 1;
});

// Mutable enumeration over Pair(A, B)
pair_enumerate!((i, x) in mut t {
    println!("enumerate_mut {}: {}", i, x.foo());
    x.bar_mut();
    assert_eq!(i, real_idx);
    real_idx += 1;
});

Sources: tests/test_tuple_for_each.rs(L84 - L90)  tests/test_tuple_for_each.rs(L99 - L105) 

Implementation Details

Macro Export and Documentation

Both macro types are exported using #[macro_export] and include generated documentation with usage examples specific to the tuple struct name.

Code Generation Pipeline for Macros

flowchart TD
StructName["Tuple Struct Name"]
pascal_to_snake["pascal_to_snake()"]
MacroNames["Macro Identifiers"]
FieldCount["Field Count"]
FieldLoops["Field Generation Loops"]
ForEachVecs["for_each & for_each_mut Vectors"]
EnumVecs["enumerate & enumerate_mut Vectors"]
Documentation["gen_doc() Function"]
DocStrings["Generated Doc Strings"]
QuoteExpansion["quote! Macro"]
FinalTokens["Generated macro_rules! Definitions"]

DocStrings --> QuoteExpansion
Documentation --> DocStrings
EnumVecs --> QuoteExpansion
FieldCount --> FieldLoops
FieldLoops --> EnumVecs
FieldLoops --> ForEachVecs
ForEachVecs --> QuoteExpansion
MacroNames --> Documentation
MacroNames --> QuoteExpansion
QuoteExpansion --> FinalTokens
StructName --> pascal_to_snake
pascal_to_snake --> MacroNames

The generation process involves:

  1. Converting struct name from PascalCase to snake_case
  2. Creating macro identifiers with _for_each and _enumerate suffixes
  3. Generating field access code for each tuple position
  4. Creating documentation strings with examples
  5. Assembling everything into macro_rules! definitions using quote!

Sources: src/lib.rs(L58 - L122)  src/lib.rs(L26 - L56) 

Field Access Pattern

All generated macros use numeric field access (.0, .1, .2) since tuple structs have unnamed fields. The field index is determined by the position in the tuple struct definition.

Field PositionAccess PatternGenerated Index
First field$tuple.00(for enumerate)
Second field$tuple.11(for enumerate)
Third field$tuple.22(for enumerate)

Sources: src/lib.rs(L69 - L83)