Boiethios
Boiethios

Reputation: 42849

Repetition inside an optional pattern

I'm trying to generate a struct optionally, based on the presence of an optional pattern $( … )?:

macro_rules! accounts_struct {
    (
        $( #[seeds: struct $StructSeedsName:ident] )?
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
        
        $(
            pub struct $StructSeedsName {
                $(
                    pub $account: u8,
                )*
            }
        )?
    }
}

accounts_struct! {
    #[seeds: struct Seeds]
    struct Accounts {
        pub foo,
        pub bar,
    }
}

Playground.

Unfortunately, it looks like I'm not allowed to do that:

error: meta-variable `StructSeedsName` repeats 1 time, but `account` repeats 2 times
  --> src/lib.rs:16:10
   |
16 |           $(
   |  __________^
17 | |             pub struct $StructSeedsName {
18 | |                 $(
19 | |                     pub $account: u8,
20 | |                 )*
21 | |             }
22 | |         )?
   | |_________^

What can I use as a workaround?

Upvotes: 1

Views: 371

Answers (1)

Alexey S. Larionov
Alexey S. Larionov

Reputation: 7937

As a last resort, you can repeat yourself like so, to cover a case when the optional section is present and when it's not

macro_rules! accounts_struct {
    (
        #[seeds: struct $StructSeedsName:ident]
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
        
        
        pub struct $StructSeedsName {
            $(
                pub $account: String,
            )*    
        }
    };
    (
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
    };
}

Upvotes: 1

Related Questions