Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get index of macro repetition single element

Tags:

macros

rust

I need to get index of macro repetition element to write next code:

struct A {
    data: [i32; 3]
}

macro_rules! tst {
    ( $( $n:ident ),* ) => {
        impl A {
            $(
                fn $n(self) -> i32 {
                    self.data[?] // here I need the index
                }
            ),*
        }
    }
}

I know one way to do it: just tell user to write index by hands:

( $( $i:ident => $n:ident ),* )

But is there a more elegant way which does not require user's action?

like image 666
Lodin Avatar asked Sep 28 '15 06:09

Lodin


Video Answer


1 Answers

The easiest way is to use recursion, like so:

struct A {
    data: [i32; 3]
}

macro_rules! tst {
    (@step $_idx:expr,) => {};

    (@step $idx:expr, $head:ident, $($tail:ident,)*) => {
        impl A {
            fn $head(&self) -> i32 {
                self.data[$idx]
            }
        }

        tst!(@step $idx + 1usize, $($tail,)*);
    };

    ($($n:ident),*) => {
        tst!(@step 0usize, $($n,)*);
    }
}

tst!(one, two, three);

fn main() {
    let a = A { data: [10, 20, 30] };
    println!("{:?}", (a.one(), a.two(), a.three()));
}

Note that I changed the method to take &self instead of self, since it made writing the example in the main function easier. :)

Each step in the recursion just adds 1 to the index. It is a good idea to use "typed" integer literals to avoid compilation slowdown due to lots and lots of integer inference.

like image 60
DK. Avatar answered Sep 21 '22 14:09

DK.