Macro simplification

I have the following code:

#[macro_export]
macro_rules! make_pub_id {
    ($name:ident) => {
        #[derive(Clone, Eq, PartialEq, Hash, Copy, PartialOrd, Ord)]
        pub struct $name(pub u64);

        impl $name {
            pub fn next(&self) -> $name {
                $name(self.0 + 1)
            }

            pub fn zero() -> $name {
                $name(0)
            }
        }
    };
}

#[macro_export]
macro_rules! make_priv_id {
    ($name:ident) => {
        #[derive(Clone, Eq, PartialEq, Hash, Copy, PartialOrd, Ord)]
        struct $name(pub u64);

        impl $name {
            pub fn next(&self) -> $name {
                $name(self.0 + 1)
            }

            pub fn zero() -> $name {
                $name(0)
            }
        }
    };
}

the only difference between the two is that one is 'pub struct' and one is 'struct'

Is there a way to unify / simplify this ?

You can match vis fragment specifier:

macro_rules! make_id {
    ($vis:vis $name:ident) => {
        #[derive(Clone, Eq, PartialEq, Hash, Copy, PartialOrd, Ord)]
        $vis struct $name(pub u64);

        impl $name {
            pub fn next(&self) -> $name {
                $name(self.0 + 1)
            }

            pub fn zero() -> $name {
                $name(0)
            }
        }
    };
}

Playground

2 Likes

Worked, thanks! TIL :vis can match empty.

1 Like