Q:

Is it possible to define a macro that generates a static array of all enum values from numbers?

I want to write this code:
enum Foo {
    A1 = 1,
    A17 = 17,
    A42 = 42,
}

static FOO_VALUES: [Foo; 3] = [Foo::A1, Foo::A17, Foo::A42];

impl Foo {
    fn to_num(self) -> i32 {
        match self {
            Foo::A1 => 1,
            //...
        }
        fn from_num(a: i32) -> Result<Foo, ()> {
            //...
        }
    }
}

To prevent errors, I thought to generate the code with macros:
macro_rules! define_foo_enum {
    ($Name:ident { $($Variant:ident),* }) => {
        pub enum $Name {
            $(concat_ident!(A, $Variant)),*,
        }
        const concat_indent!($Name, _VALUES): &'static [$Name] = &[$($Name::concat_ident!(A, $Variant)),*];
    }
}

The macro would be used like define_foo_enum!(1, 17, 42);
This code does not compile, I suppose because concat_ident! does not work in the way that I'm attempting to use it. Additionally, I'm supplying numbers to the macro, not identifiers, but I don't know what type to use, tt?
I'm using Rust 1.17.

A:

My mashup crate makes it possible to form concatenated identifiers like you intended. It supports any stable Rust compiler since 1.15, although in the implementation below I have used an associated constant which requires Rust 1.20+.
#[macro_use]
extern crate mashup;

macro_rules! define_foo_enum {
    ($name:ident { $($number:tt),* }) => {
        mashup! {
            $(
                m["A" $number] = A $number;
            )*
        }
        m! {
            #[derive(Debug, PartialEq)]
            pub enum $name {
                $(
                    "A" $number,
                )*
            }
            impl $name {
                pub const VALUES: &'static [Self] = &[$($name::"A" $number,)*];
            }
        }
    }
}

define_foo_enum!(Foo { 1, 17, 42 });

fn main() {
    assert_eq!(Foo::VALUES, [Foo::A1, Foo::A17, Foo::A42]);
}

