I have an existing macro definition that captures the attributes. Inside that definition, I'm trying to filter and set the attributes selectively.
I have a peculiar problem where I have to set attributes for match arms in one of these cases.
macro_rules! set_mytrait {
(
$target:ident
$(
$( #[$cfgs:meta] )*
$field:ident
),*
$(,)*
) => {
impl $crate::MyTrait for $target
{
fn perform(&self) -> Option<&(dyn $crate::Error + 'static)> {
match self { $(
// Replace the below attributes with a filter function that returns only some of the attributes
$(#[$cfgs])*
$field => {
// doSomething($field);
None
}
)* }
}
}
}
}
I know that we cannot yet use macros in attributes according to this.
Apart from that, I've tried two options and both seem to have hit roadblocks.
Option 1
Approach: Using macro that takes just attributes as arguments and returns filtered attributes.
Implementation:
piped_attribs
#[macro_export]
macro_rules! piped_attribs {
(
$( $attr:tt )*
) => {
// Use filter logic here
$( #[$attr] )*
};
}
called_at
match self { $(
$crate::piped_attribs! { $( $cfgs ),* }
$field => {
// doSomething($field)
None
}
)* }
Problem: Seems like emitting attributes doesn't work in this context and I require to attach it to an item (source)
Option 2
Approach: Using macro that takes in two args. One for attributes and next for the match arm.
Implementation:
piped_attribs
#[macro_export]
macro_rules! piped_attribs {
(
[ $( $attr:tt )* ]
{ $rest: tt }
) => {
// Use filtering logic here
$( #[$attr] )*
$rest,
};
}
called at
match self { $(
$crate::piped_attribs! {
[$( $cfgs ),*]
{$field => {
// doSomething($field);
None
}}
}
)* }
Problem: I discovered that apparently we cannot return match "arms" from an attribute as of now. issue
Finally... the question
Is any of these approaches feasible and if not, is there a better way to look at this issue?