Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to apply constraints on identifiers passed into a macro?

Tags:

macros

rust

Since Rust doesn't yet support concat_idents in stable, it may be necessary to pass in multiple similar identifiers as arguments.

This allows for accidentally passing in the wrong positional arguments.

Is there a way to check the identifiers match some basic rules such as "contains text", "starts with", "ends with", etc.

struct_bitflag_flag_fn_impl!(
    MyStructType, my_struct_flag::SELECT,
    select_test, select_set, select_clear, select_set_bool, select_toggle);
struct_bitflag_flag_fn_impl!(
    MyStructType, my_struct_flag::HIDDEN,
    hidden_test, hidden_set, hidden_clear, hidden_toggle, hidden_set_bool);

//  Humans make mistakes, how to prevent?     ->  ^^^^^^         ^^^^^^^^
//  (arguments may be transposed by accident)
like image 596
ideasman42 Avatar asked Mar 10 '23 22:03

ideasman42


1 Answers

No, but you can make it easier to spot mistakes by adding structure to the macro instead of just passing comma-separated names:

macro_rules! my_macro {
    // Note: parameter must be in the right order; they're not general
    // keyword arguments.
    ($name:ident, set=$set:ident, get=$get:ident, toggle=$toggle:ident)
    =>
    (
        {}
    )
}

fn main() {
    // Correct usage
    my_macro!(foo, set=my_set, get=my_get, toggle=my_toggle);
    // Not right, but easier to spot with the keyword argument-style usage.
    my_macro!(foo, set=my_set, get=my_toggle, toggle=my_get);
}

Playground

I've used something that looks like keyword arguments, but you could invent things with some operators like my_macro!(foo, =my_set, *my_get, !my_toggle) if that worked better for you.

like image 106
Chris Emerson Avatar answered Apr 28 '23 12:04

Chris Emerson