1macro_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}