1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 3 macro_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 17 macro_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 31 macro_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 41 macro_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 71 macro_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 97 macro_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 105 macro_rules! check_keyword_matches { 106 (enum enum) => {}; 107 (pub pub) => {}; 108 } 109