/// Internal namespace. pub( crate ) mod private { use crate::exposed::*; use type_constructor::prelude::*; types! { /// /// Attribute which is inner. /// #[ derive( Debug, PartialEq, Eq, Clone ) ] pub single AttributeInner : syn::Attribute; } impl syn::parse::Parse for AttributeInner { fn parse( input : ParseStream< '_ > ) -> Result< Self > { let input2; Ok( Self( syn::Attribute { pound_token : input.parse()?, style : syn::AttrStyle::Inner( input.parse()? ), bracket_token : bracketed!( input2 in input ), path : input2.call( syn::Path::parse_mod_style )?, tokens : input2.parse()?, })) // Ok( ( input.call( syn::Attribute::parse_inner )? ).into() ) } } impl quote::ToTokens for AttributeInner { fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) { self.0.to_tokens( tokens ); } } /// /// Pair of syntax elements. /// // zzz : use pair #[ derive( Debug, PartialEq, Eq, Clone ) ] pub struct Pair< T1, T2 > ( pub T1, pub T2 ) where T1 : syn::parse::Parse + quote::ToTokens, T2 : syn::parse::Parse + quote::ToTokens, ; impl< T1, T2 > syn::parse::Parse for Pair< T1, T2 > where T1 : syn::parse::Parse + quote::ToTokens, T2 : syn::parse::Parse + quote::ToTokens, { fn parse( input : ParseStream< '_ > ) -> Result< Self > { Ok( Self( input.parse()?, input.parse()? ) ) } } impl< T1, T2 > quote::ToTokens for Pair< T1, T2 > where T1 : syn::parse::Parse + quote::ToTokens, T2 : syn::parse::Parse + quote::ToTokens, { fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) { self.0.to_tokens( tokens ); self.1.to_tokens( tokens ); } } // zzz : publish module cotainer with good prelude /// /// Parse as much elements as possible. /// #[ derive( Debug, PartialEq, Eq, Clone ) ] pub struct Many< T > ( Vec< T > ) where T : quote::ToTokens, ; impl< T > Many< T > where T : quote::ToTokens, { /// Constructor. pub fn new() -> Self { Self( Vec::new() ) } } impl< T > quote::ToTokens for Many< T > where T : quote::ToTokens, { fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) { use crate::quote::TokenStreamExt; tokens.append_all( self.0.iter() ); // self.0.to_tokens( tokens ); } } impl syn::parse::Parse for Many< AttributeInner > { fn parse( input : ParseStream< '_ > ) -> Result< Self > { let mut result = Self::new(); while input.peek( Token![ # ] ) { result.0.push( input.parse()? ); } Ok( result ) } } impl syn::parse::Parse for Many< syn::Item > { fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > { let mut items = vec![]; while !input.is_empty() { let item : syn::Item = input.parse()?; items.push( item ); } Ok( Self( items ) ) } } // xxx : macro? impl< T > core::ops::Deref for Many< T > where T : quote::ToTokens, { type Target = Vec< T >; fn deref( &self ) -> &Self::Target { &self.0 } } // xxx : macro? impl< T > From< Vec< T > > for Many< T > where T : quote::ToTokens, { fn from( src : Vec< T > ) -> Self { Self( src ) } } impl< T > From< Many< T > > for Vec< T > where T : quote::ToTokens, { fn from( src : Many< T > ) -> Self { src.0 } } /// /// Attribute and ident. /// pub type AttributedIdent = Pair< Many< AttributeInner >, syn::Ident >; impl From< syn::Ident > for AttributedIdent { fn from( src : syn::Ident ) -> Self { Self( Vec::new().into(), src ) } } impl From< AttributedIdent > for syn::Ident { fn from( src : AttributedIdent ) -> Self { src.1 } } // impl syn::parse::Parse for AttributedIdent // { // fn parse( input : ParseStream< '_ > ) -> Result< Self > // { // Ok( Self( input.parse()?, input.parse()? ) ) // } // } // // impl quote::ToTokens for AttributedIdent // { // fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) // { // self.0.to_tokens( tokens ); // self.1.to_tokens( tokens ); // } // } /// /// Many items. /// // #[ allow( dead_code ) ] #[ derive( Debug ) ] pub struct Items ( pub Vec< syn::Item >, ); impl syn::parse::Parse for Items { fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > { let mut items = vec![]; while !input.is_empty() { let item : syn::Item = input.parse()?; items.push( item ); } Ok( Self( items ) ) } } impl quote::ToTokens for Items { fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream ) { // use quote::ToTokens; self.0.iter().for_each( | item | item.to_tokens( tokens ) ); } } } /// Exposed namespace of the module. pub mod exposed { pub use super::prelude::*; pub use super::private:: { AttributeInner, Pair, Many, AttributedIdent, Items, }; } pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude { }