1

I have created an enum to represent a set of built in types and I am trying to implement fmt::Display by using the existing implementations, however the code seems very repetitive especially as the list of types grows. Is there any cleaner way to achieve this by calling the function once?

pub enum NodeVal {
    I8(i8),
    I16(i16),
    I32(i32),
}

impl fmt::Display for NodeVal {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            NodeVal::I8(v) => ::std::fmt::Display::fmt(&v, f),
            NodeVal::I16(v) => ::std::fmt::Display::fmt(&v, f),
            NodeVal::I32(v) => ::std::fmt::Display::fmt(&v, f)
        }
    }
}
zman
  • 203
  • 2
  • 7
  • the `polymorphic_enum!` macro provided [here](https://stackoverflow.com/a/63849947/11527076) can help apply the same code to each variant of an enum. – prog-fh Oct 22 '20 at 17:47

1 Answers1

1

You can use macros:

use std::fmt;

// macro that implements fmt::Display for each passed variant of `NodeVal`
macro_rules! display_node_val {
  ($($x:ident),*) => {
    impl fmt::Display for NodeVal {
      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
          $( NodeVal::$x(v) => fmt::Display::fmt(&v, f), )*
        }
      }
    }
  };
}

We can use the above macro as shown below:

pub enum NodeVal {
  I8(i8),
  I16(i16),
  I32(i32),
}

display_node_val!(I8, I16, I32);

fn main() {
  println!("{}", NodeVal::I16(3))
}

// => 3

Here is a link to a Rust playground

The code above was derived from this answer

Ibraheem Ahmed
  • 11,652
  • 2
  • 48
  • 54