1

Original demand: I want to implement a macro that converts Foo::* to Bar::*.

Pseudo code will look like this:

macro_rules! convert_foo_to_bar {
    ($v: ty, $p: path) => (<$v>::$p.name)
}

// convert_foo_to_bar!(Bar, Foo::A) -> Bar::A

While $p.name refers to A.

Jason Sui
  • 13
  • 3

1 Answers1

1

You can match the Foo::A using Foo::$variant:ident to get A as $variant like this:

macro_rules! convert_foo_to_bar {
    ($v: ty, Foo::$variant:ident) => (<$v>::$variant)
}

Playground

If you need to convert a variable, you will need to use a normal function such as this:

fn convert_foo_to_bar(foo: Foo) -> Bar {
  match foo {
    Foo::A => Bar::A,
    Foo::B => Bar::B,
    // .. for all of your variants
  }
}
Filipe Rodrigues
  • 1,843
  • 2
  • 12
  • 21
  • Hi, I have tried your solution, but now I have one more question: if I have `let a = Foo::A`, how to deal with `convert_foo_to_bar!(Bar, a)` ? – Jason Sui Aug 02 '20 at 13:17
  • @JasonSui I don't think a macro would be able to get information about what variant a variable `a` is, so you'd use a function, see the update on my answer. – Filipe Rodrigues Aug 02 '20 at 13:30
  • If instead of `Bar`, you need another type, you could create a new function, with the same match, or instead, put the match inside of a macro, replacing `Bar::` with `<$v>::`, just like in your original macro. – Filipe Rodrigues Aug 02 '20 at 13:32
  • Okay, I get it. Maybe I should get a further understand about the Rust Macro. – Jason Sui Aug 03 '20 at 04:48