::macro_rules_attribute

Use declarative macros in attribute or derive position.

```rust ,ignore macrorules! myfancy_decorator { /* … */ }

[apply(myfancydecorator!)]

struct Foo { /* … */ } ```

```rust ,ignore macro_rules! MyFancyDerive { /* … */ }

[derive(MyFancyDerive!)]

struct Foo { /* … */ } ```

Latest version Documentation License

Motivation

macro_rules! macros can be extremely powerful, but their call-site ergonomics are sometimes not great, especially when decorating item definitions.

Indeed, compare:

rust ,ignore foo! { struct Struct { some_field: SomeType, } }

to:

```rust ,ignore

[foo]

struct Struct { some_field: SomeType, } ```

  1. The former does not scale well, since it leads to rightward drift and "excessive" braces.

  2. But on the other hand, the latter requires setting up a dedicated crate for the compiler, a proc-macro crate. And 99% of the time this will pull the [::syn] and [::quote] dependencies, which have a non-negligible compile-time overhead (the first time they are compiled).


Solution

With this crate's #[[apply]] and #[[derive]] attributes, it is now possible to use proc_macro_attribute syntax to apply a macro_rules! macro:

```rust

[macro_use]

extern crate macrorulesattribute;

macro_rules! foo { // … # ( $($tt:tt)* ) => () }

macro_rules! Bar { // … # ( $($tt:tt)* ) => () }

[apply(foo)]

[derive(Debug, Bar!)]

struct Struct { some_field: SomeType, } #

fn main() {}

```

without even depending on [::quote], [::syn] or [::proc-macro2], for fast compile times.

Example

Deriving getters for a (non-generic) struct:

```rust

[macro_use]

extern crate macrorulesattribute;

macrorules! makegetters {( $(#[$structmeta:meta])* $structvis:vis struct $StructName:ident { $( $(#[$fieldmeta:meta])* $fieldvis:vis // this visibility will be applied to the getters instead $fieldname:ident : $fieldty:ty ),* $(,)? } ) => ( // First, generate the struct definition we have been given, but with // private fields instead. $(#[$structmeta])* $structvis struct $StructName { $( $(#[$fieldmeta])* // notice the lack of visibility => private fields $fieldname: $field_ty, )* }

// Then, implement the getters:
impl $StructName {
    $(
        #[inline]
        $field_vis
        fn $field_name (self: &'_ Self)
            -> &'_ $field_ty
        {
            &self.$field_name
        }
    )*
}

)}

mod example { #[apply(make_getters)] /// The macro handles meta attributes such as docstrings pub struct Person { pub name: String,

    pub
    age: u8,
}

} use example::Person;

fn isnewborn (person: &'_ Person) -> bool { // person.age == 0 // ^ error[E0616]: field age of struct example::Person is private *person.age() == 0 }

fn main() {}

```

Debugging

An optional compilation feature, "verbose-expansions" can be used to print at compile-time the exact output of each macro invocation from this crate:

toml [dependencies] macro_rules_attribute.version = "..." macro_rules_attribute.features = ["verbose-expansions"]

Bonus tricks

derive aliases

```rust

fn main() {}

[macro_use]

extern crate macrorulesattribute;

derive_alias! { #[derive(Ord!)] = #[derive(PartialEq, Eq, PartialOrd, Ord)]; }

[derive(Debug, Clone, Copy, Ord!)]

struct Foo { // … } ```

cfg aliases

```rust

fn main() {}

[macro_use]

extern crate macrorulesattribute;

attributealias! { #[apply(complexcfg!)] = #[cfg( any( any( foo, feature = "bar", ), all( targetos = "fenestrations", not(targetarch = "Pear"), ), ), )]; }

[apply(complex_cfg!)]

mod some_item { /* … */ } ```