@@ -31,6 +31,50 @@ impl BufferGeneric {
3131 }
3232}
3333
34+ pub fn has_attr ( field : & syn:: Field , id : & str ) -> bool {
35+ field. attrs . iter ( ) . any ( |attr| {
36+ let syn:: Meta :: Path ( path) = & attr. meta else {
37+ return false ;
38+ } ;
39+ path. segments
40+ . last ( )
41+ . iter ( )
42+ . any ( |& segment| segment. ident == id)
43+ } )
44+ }
45+
46+ pub fn meta_type ( field : & syn:: Field ) -> syn:: Type {
47+ field
48+ . attrs
49+ . iter ( )
50+ . filter_map ( |attr| {
51+ use syn:: Meta :: * ;
52+ match & attr. meta {
53+ List ( list) => Some ( list) ,
54+ _ => None ,
55+ }
56+ } )
57+ . find ( |list| {
58+ list. path
59+ . segments
60+ . last ( )
61+ . iter ( )
62+ . any ( |& segment| segment. ident == "property" )
63+ } )
64+ . map ( |list| {
65+ list. parse_args :: < syn:: Type > ( )
66+ . expect ( "Arguments to property attribute should be a valid type" )
67+ } )
68+ . expect ( "fields must be annotated with the property attribute" )
69+ }
70+
71+ pub fn is_unit_tuple ( ty : & syn:: Type ) -> bool {
72+ match ty {
73+ syn:: Type :: Tuple ( tup) => tup. elems . is_empty ( ) ,
74+ _ => false ,
75+ }
76+ }
77+
3478pub fn buffer_generic ( generics : & syn:: Generics ) -> Option < BufferGeneric > {
3579 let type_param = |param : & syn:: GenericParam | {
3680 if let syn:: GenericParam :: Type ( type_param) = param {
@@ -46,41 +90,52 @@ pub fn buffer_generic(generics: &syn::Generics) -> Option<BufferGeneric> {
4690 None
4791 }
4892 } ;
49- let buffer_bound = |id : & ' static str | {
50- move |bound : & syn:: TraitBound | match bound. path . segments . last ( ) . as_ref ( ) {
93+ let is_buffer_bound = |id : & ' static str | {
94+ move |bound : syn:: TraitBound | match bound. path . segments . last ( ) . as_ref ( ) {
5195 Some ( segment) => segment. ident == id,
5296 None => false ,
5397 }
5498 } ;
5599 for param in generics. params . iter ( ) . filter_map ( type_param) {
56- if let Some ( _ ) = param
100+ if param
57101 . bounds
58102 . iter ( )
59103 . filter_map ( trait_bound)
60- . find ( buffer_bound ( "Ump" ) )
104+ . any ( is_buffer_bound ( "Ump" ) )
61105 {
62106 return Some ( BufferGeneric :: Ump ( param. clone ( ) ) ) ;
63107 } ;
64- if let Some ( _ ) = param
108+ if param
65109 . bounds
66110 . iter ( )
67111 . filter_map ( trait_bound)
68- . find ( buffer_bound ( "Bytes" ) )
112+ . any ( is_buffer_bound ( "Bytes" ) )
69113 {
70114 return Some ( BufferGeneric :: Bytes ( param. clone ( ) ) ) ;
71115 } ;
72- if let Some ( _ ) = param
116+ if param
73117 . bounds
74118 . iter ( )
75119 . filter_map ( trait_bound)
76- . find ( buffer_bound ( "Buffer" ) )
120+ . any ( is_buffer_bound ( "Buffer" ) )
77121 {
78122 return Some ( BufferGeneric :: UmpOrBytes ( param. clone ( ) ) ) ;
79123 } ;
80124 }
81125 None
82126}
83127
128+ pub fn std_only_attribute ( is_std_only : bool ) -> TokenStream {
129+ if is_std_only {
130+ quote ! {
131+ #[ cfg( feature = "std" ) ]
132+ #[ cfg_attr( docsrs, doc( cfg( feature = "std" ) ) ) ]
133+ }
134+ } else {
135+ TokenStream :: new ( )
136+ }
137+ }
138+
84139pub fn rebuffer_generics ( repr : Representation ) -> TokenStream {
85140 match repr {
86141 Representation :: Ump => quote ! {
@@ -146,3 +201,18 @@ pub fn try_rebuffer_generics(repr: Representation) -> TokenStream {
146201 } ,
147202 }
148203}
204+
205+ pub fn parse_via_args ( input : syn:: parse:: ParseStream ) -> syn:: Type {
206+ let syn:: ExprParen { expr, .. } = input
207+ . parse ( )
208+ . expect ( "Bracketed expression should follow size arg" ) ;
209+
210+ let syn:: Expr :: Path ( path) = * expr else {
211+ panic ! ( "Via argument should contain a path type" ) ;
212+ } ;
213+
214+ syn:: Type :: Path ( syn:: TypePath {
215+ qself : path. qself ,
216+ path : path. path ,
217+ } )
218+ }
0 commit comments