Search code examples
rustmacrosdstrust-macros

How can I get "Bar" from "Foo::Bar" in rust macro?


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.


Solution

  • 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
      }
    }