syn_mid/
macros.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3macro_rules! ast_struct {
4    (
5        [$($attrs_pub:tt)*]
6        struct $name:ident $($rest:tt)*
7    ) => {
8        #[cfg_attr(feature = "clone-impls", derive(Clone))]
9        $($attrs_pub)* struct $name $($rest)*
10    };
11
12    ($($tt:tt)*) => {
13        strip_attrs_pub!(ast_struct!($($tt)*));
14    };
15}
16
17macro_rules! ast_enum {
18    (
19        [$($attrs_pub:tt)*]
20        enum $name:ident $($rest:tt)*
21    ) => (
22        #[cfg_attr(feature = "clone-impls", derive(Clone))]
23        $($attrs_pub)* enum $name $($rest)*
24    );
25
26    ($($tt:tt)*) => {
27        strip_attrs_pub!(ast_enum!($($tt)*));
28    };
29}
30
31macro_rules! ast_enum_of_structs {
32    (
33        $(#[$enum_attr:meta])*
34        $pub:ident $enum:ident $name:ident $body:tt
35    ) => {
36        ast_enum!($(#[$enum_attr])* $pub $enum $name $body);
37        ast_enum_of_structs_impl!($pub $enum $name $body);
38    };
39}
40
41macro_rules! ast_enum_of_structs_impl {
42    (
43        $pub:ident $enum:ident $name:ident {
44            $(
45                $(#[$variant_attr:meta])*
46                $variant:ident $( ($member:ident) )*,
47            )*
48        }
49    ) => {
50        check_keyword_matches!(pub $pub);
51        check_keyword_matches!(enum $enum);
52
53        $(
54            $(
55                impl From<$member> for $name {
56                    fn from(e: $member) -> $name {
57                        $name::$variant(e)
58                    }
59                }
60            )*
61        )*
62
63        generate_to_tokens! {
64            ()
65            tokens
66            $name { $($variant $($member)*,)* }
67        }
68    };
69}
70
71macro_rules! generate_to_tokens {
72    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
73        generate_to_tokens!(
74            ($($arms)* $name::$variant => {})
75            $tokens $name { $($next)* }
76        );
77    };
78
79    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident $member:ident, $($next:tt)*}) => {
80        generate_to_tokens!(
81            ($($arms)* $name::$variant(_e) => quote::ToTokens::to_tokens(_e, $tokens),)
82            $tokens $name { $($next)* }
83        );
84    };
85
86    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
87        impl quote::ToTokens for $name {
88            fn to_tokens(&self, $tokens: &mut proc_macro2::TokenStream) {
89                match self {
90                    $($arms)*
91                }
92            }
93        }
94    };
95}
96
97macro_rules! strip_attrs_pub {
98    ($mac:ident!($(#[$m:meta])* $pub:ident $($tt:tt)*)) => {
99        check_keyword_matches!(pub $pub);
100
101        $mac!([$(#[$m])* $pub] $($tt)*);
102    };
103}
104
105macro_rules! check_keyword_matches {
106    (enum enum) => {};
107    (pub pub) => {};
108}