Timmmm
Timmmm

Reputation: 97108

Rust macro to convert between identical enums

Suppose I have these two identical enums (don't ask why):

enum Foo {
  A,
  B,
  C,
  D,
}

enum Bar {
  A,
  B,
  C,
  D,
}

Is there any way to use a macro to automatically convert between them, without having to write this tedious code:

let f: Foo = match b {
  Bar::A => Foo::A,
  Bar::B => Foo::B,
  Bar::C => Foo::C,
  Bar::D => Foo::D,
};

Bonus points: is it possible to do it for two identical structs?

Edit: A couple of clarifications - at least one of the enums already exists in code and can't be edited (in my case it is generated code but it could also be from an external crate). Also I realise you can do this with proc macros because they can basically do anything, but I'm looking for something simpler if it exists.

If it's not possible that is a valid answer too.

Upvotes: 2

Views: 943

Answers (1)

phimuemue
phimuemue

Reputation: 36081

If you accept to repeat the enum variants once, the following might help:

enum Foo {
  A,
  B,
  C,
  D,
}

enum Bar {
  A,
  B,
  C,
  D,
}

macro_rules! convert_enum{($src: ident, $dst: ident, $($variant: ident,)*)=> {
    impl From<$src> for $dst {
        fn from(src: $src) -> Self {
            match src {
                $($src::$variant => Self::$variant,)*
            }
        }
    }
}}

convert_enum!(Foo, Bar, A, B, C, D,);

This could, of course, already generate the inverse direction. Moreover, I think it can be adapted for structs or enums holding more complex variants.

Upvotes: 3

Related Questions