Conditional Code in Macro

I'm working on an error macro to make it easier to generate errors in my code. I always want to capture a backtrace using the Backtrace crate. The problem I'm having is that I want to support enum options that both have and do not have a type: ErrOp1 and ErrOp1(String). This is easy enough; however, when it comes time to write the Display impl, I need a way to write code conditionally on if there is a type or not.

Here's the basic sketch of my macro (the From impls are remove for brevity):

macro_rules! my_error {
    ( $err_name:ident $( $err_op:ident $( ($err_type:ty) )? $(,)? )+ ) => {
        use backtrace::Backtrace;

        pub enum $err_name {
            $( $err_op { $(err: $err_type,)? bt: Backtrace }, )+

        impl std::error::Error for $err_name {}

        impl std::fmt::Display for $err_name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                match self {
                        Self::$err_op {$(err: ,)? bt } => {
                            $( write!(f, "{} from\n", err)?;  )?
                            write!(f, "{:?}", bt)


The problem is with the two lines: Self::$err_op {$(err: ,)? bt } => { and $( write!(f, "{} from\n", err)?; )?. They both rely on if $err_type exists or not, but I have no place to use this variable in the code.

I was able to make the second one work by creating a NOOP macro: macro_rules! no_op { ($i:ty) => {} } and applying it before the write!: $( no_op!($err_type); write!(f, "{} from\n", err)?; )?

However, I cannot seem to find a way to use my same trick with the enum field. Is there a way to do this?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.