Generic referencing enum inner data

I was thinking of a macro like

macro_rules! Foo {
    ($p:pat) => {
        Foo::Bar($p) | Foo::Bink($p)
    }
}

or perhaps something like

enum Baz {
    Variant1 {
        x: u32,
        y: String,
        z: bool,
    },
    Variant2 {
        x: u32,
        z: bool,
        qux: fn(),
    }
}

macro_rules! Baz {
    ($($field:ident $(: $p:pat)?,)* ..) => {
        Baz::Variant1{ $($field $(: $p)?,)* .. } | Baz::Variant2{ $($field $(: $p)?,)* .. }
    }
}

(playground)

Maybe a macro to create such a macros could even be useful, too, so you can just write

#[derive(Debug)]
enum Baz {
    Variant1 {
        x: u32,
        y: String,
        z: bool,
    },
    Variant2 {
        x: u32,
        z: bool,
        qux: fn(),
    }
}

define_enum_macro!(Baz, Variant1, Variant2);

fn demonstration2() {
    let x = Baz::Variant1 { x: 42, y: "hello".into(), z: false };
    let Baz!{ z, .. } = &x;
    println!("{:?} with `z` being {:?}", x, z);
}

(playground)


Note that it’s usually easier to just store a common field outside of the enum; the only downside I’m aware of is that that’s sometimes resulting in less compact type layout (but that’s arguably a problem that might be fixable in different ways, too), other than that it should be equivalent. I’m referring to the approach

struct Foo {
    value: u32,
    kind: FooKind,
}

enum FooKind {
    Bar,
    Bink,
}

that @alice mentioned above.

2 Likes