1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Provides a way to alias mutliple derives as one:
//! ```rust
//! use derive_alias::derive_alias;
//!
//! // Generates a macro (`derive_cmp`) that will attach the listed derives to a given item
//! derive_alias! {
//!     derive_cmp => #[derive(Eq, PartialEq, Ord, PartialOrd)]
//! }
//!
//! // Attach the derives to `Foo`
//! derive_cmp! { struct Foo; }
//! ```
//!
//! You can create multiple aliases at a time:
//! ```rust
//! # use derive_alias::derive_alias;
//!
//! derive_alias! {
//!     derive_cmp => #[derive(Eq, PartialEq, Ord, PartialOrd)],
//!     derive_other => #[derive(Copy, Clone)]
//! }
//!
//! derive_cmp! { struct Foo; }
//! derive_other! { struct Bar; }
//! ```

/// Refer to the [crate level documentation](crate) for details.
#[macro_export]
macro_rules! derive_alias {
    ($($name:ident => #[derive($($derive:ident),*)] $(,)?)*) => {
        $(
            macro_rules! $name {
                ($i:item) => {
                    #[derive($($derive),*)]
                    $i
                }
            }
        )*
    }
}

#[cfg(test)]
mod tests {
    use std::fmt::Debug;

    derive_alias! {
        derive_one => #[derive(Copy, Clone, Debug)],
        derive_two => #[derive(Eq, PartialEq, Ord, PartialOrd)]
    }

    derive_one! {
        struct Foo(i32);
    }

    derive_two! {
        struct Bar(i32);
    }

    #[test]
    fn a_test() {
        assert_impl_one(Foo(100));
        assert_impl_two(Bar(200));
    }

    fn assert_impl_one<T>(_: T)
    where
        T: Copy + Clone + Debug,
    {
    }

    fn assert_impl_two<T>(_: T)
    where
        T: Eq + PartialEq + Ord + PartialOrd,
    {
    }

    #[allow(unused_macros)]
    mod test_trailing_comma {
        derive_alias! {
            foo => #[derive()]
            bar => #[derive()]
            baz => #[derive()]
        }

        derive_alias! {
            foo => #[derive()],
            bar => #[derive()],
            baz => #[derive()],
        }
    }
}