derive_for/
lib.rs

1/// Defines several structs each using the same derive procedures.
2/// ## Example
3/// ```
4/// #[macro_use] extern crate derive_for;
5/// derive_for!(
6/// ( Clone, Debug, PartialEq, Eq);
7/// pub struct Foo{a: i32, name: String};
8/// pub struct Bar(u32, u32);
9/// );
10/// ```
11#[macro_export]
12macro_rules! derive_for {
13    // Derive tuple
14    (($b:ident $(,$a:ident)*); $(#[$attr:meta])* $vis:vis struct $name:ident($($fields:tt)*); $($rest:tt)*) => {
15        #[derive($($a,)* $b)]
16        $(#[$attr])*
17        $vis struct $name($($fields)*);
18        derive_for!( ($b, $($a,)*); $($rest)*);
19    };
20    // Derive tuple with trailing derive comma
21    (($b:ident $(,$a:ident)*,); $(#[$attr:meta])* $vis:vis struct $name:ident($($fields:tt)*); $($rest:tt)*) => {
22        #[derive($($a,)* $b)]
23        $(#[$attr])*
24        $vis struct $name($($fields)*);
25        derive_for!( ($b, $($a,)*); $($rest)*);
26    };
27    // Derive struct
28    (($b:ident $(,$a:ident)*); $(#[$attr:meta])* $vis:vis struct $name:ident{ $($fields:tt)* }; $($rest:tt)*) => {
29        #[derive($($a,)* $b)]
30        $(#[$attr])*
31        $vis struct $name{ $($fields)* }
32        derive_for!( ($b, $($a,)*); $($rest)*);
33    };
34    // Derive struct with trailing derive comma
35    (($b:ident $(,$a:ident)*,); $(#[$attr:meta])* $vis:vis struct $name:ident{ $($fields:tt)* }; $($rest:tt)*) => {
36        #[derive($($a,)* $b)]
37        $(#[$attr])*
38        $vis struct $name{ $($fields)* }
39        derive_for!( ($b, $($a,)*); $($rest)*);
40    };
41    (($($_:ident,)*);) => {};
42}
43
44#[cfg(test)]
45#[macro_use]
46mod tests {
47    use crate::derive_for;
48
49    derive_for!(
50    ( Clone, Debug, PartialEq, Eq);
51    pub struct Foo{a: i32, name: String};
52    pub struct Bar(u32, u32);
53        );
54
55    #[test]
56    pub fn test() {
57        let foo = Foo {
58            a: 5,
59            name: "Hello".into(),
60        };
61        let bar = Bar(3, 6);
62
63        // Debug
64        println!("{:?}, {:?}", foo, bar);
65
66        // Eq
67        assert_eq!(
68            foo,
69            Foo {
70                a: 5,
71                name: "Hello".into()
72            }
73        );
74        assert_eq!(bar, Bar(3, 6));
75
76        // Clone
77        assert_eq!(foo, foo.clone());
78        assert_eq!(bar, bar.clone());
79    }
80}