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