Macro_rules to iterate and choose between two options

I've created a macros with the following rule:

#[macro_export]
macro_rules! mmio_registerfields {
    ($(
        $reg:ident $type:ty [$(
            $field:ident [$offset:expr, $size:expr] $({
                $($key:ident = $value:expr),+
            })?
        )*]
    ),+) => {$( <body> )+};
}

It handles the following format:

mmio_registerfields!(
    UART_RBR u32 [],
    UART_THR u32
    [
        DATA_OUTPUT [0, 8]
    ],
    UART_IER u32
    [
        RECEIVE_DATA_AVAILABLE_INT_EN [0, 1]
        {
            DISABLED = 0,
            ENABLED = 1
        }
    ]
);

How can I change it to allow specifying either [$offset:expr, $size:expr] or [$offset:expr] to allow supplying the default value of 1 as $size?

Here's a trick you might use:

Code
macro_rules! mmio_registerfields {
    ($(
        $reg:ident $type:ty [$(
            // move the $size in $(, ...)? to test for presence
            $field:ident [$offset:expr $(, $size:expr)? ] $({
                $($key:ident = $value:expr),+
            })?
        )*]
    ),+) => {
    // not sure what you were trying to do here,
    // so I simply converted it all into text
        stringify!($(
            $reg $type [$(
                $field [$offset, 1 $(* $size)?] $({
                // start with 1 and multiply by size, if there's any
                    $($key = $value),+
                })?
            )*]
        ),+)
    };
}

fn main() {
    let text = mmio_registerfields!(
        UART_RBR u32 [],
        UART_THR u32
        [
            DATA_OUTPUT [0, 8]
        ],
        UART_IER u32
        [
            RECEIVE_DATA_AVAILABLE_INT_EN [0] // size of 1 inferred
            {
                DISABLED = 0,
                ENABLED = 1
            }
        ]
    );
    println!("text: {}", text);
}

Playground Link

1 Like

Oh, that is so obvious and so cool! Thanks a lot!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.