rustrust-macros

How to use default attribute when generating struct in rust macros


I want to make the attribute #[repr] optional, if no #[repr(type)] is provided, the default #[repr(u8)] will be used

(
        #[derive($($path:path),+)]
        #[repr($repr:ty)]?
        $(#[$attr:meta])*
        $vis:vis enum $Name:ident {
            $(
                $(#[$field_attr:meta])*
                $variant:ident = $index:tt,
            )*
        }
    ) => {
        let expr = if $repr {$repr} else {u8};
        $crate::macros::paste::paste! {
            #[derive(Debug,Clone,Copy,$crate::Serialize_repr,$crate::Deserialize_repr,enum_sql::IntEnumFromSql,enum_sql::IntEnumToSql , $($path),*)]
            $(#[$attr])*
            #[serde(try_from="i16", into="i16")]
            #[repr(if $repr { $repr } else { u8 })]
            $vis enum $Name {
                $(
                    $(#[$field_attr])*
                    $variant = $index,
                )*
            }
    };

if no #[repr] attribute is provided, the default attribute #[repr(u8)] should be used

i tired #[repr(if $repr { $repr } else { u8 })] but it doesn't seem to work


Solution

  • You should make a case each for when the repr arg is supplied, and when it isn't. The isn't case should fill in the default and pass on to the is case.

    macro_rules! maybe_repr {
        ( $name:ident : $repr:ty) => { #[repr($repr)] enum $name { V } };
        ( $name:ident ) => { maybe_repr!($name : u8); };
    }
    
    maybe_repr!(U32 : u32);
    maybe_repr!(U8);