@@ -31,6 +31,50 @@ impl BufferGeneric {
31
31
}
32
32
}
33
33
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
+
34
78
pub fn buffer_generic ( generics : & syn:: Generics ) -> Option < BufferGeneric > {
35
79
let type_param = |param : & syn:: GenericParam | {
36
80
if let syn:: GenericParam :: Type ( type_param) = param {
@@ -46,41 +90,52 @@ pub fn buffer_generic(generics: &syn::Generics) -> Option<BufferGeneric> {
46
90
None
47
91
}
48
92
} ;
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 ( ) {
51
95
Some ( segment) => segment. ident == id,
52
96
None => false ,
53
97
}
54
98
} ;
55
99
for param in generics. params . iter ( ) . filter_map ( type_param) {
56
- if let Some ( _ ) = param
100
+ if param
57
101
. bounds
58
102
. iter ( )
59
103
. filter_map ( trait_bound)
60
- . find ( buffer_bound ( "Ump" ) )
104
+ . any ( is_buffer_bound ( "Ump" ) )
61
105
{
62
106
return Some ( BufferGeneric :: Ump ( param. clone ( ) ) ) ;
63
107
} ;
64
- if let Some ( _ ) = param
108
+ if param
65
109
. bounds
66
110
. iter ( )
67
111
. filter_map ( trait_bound)
68
- . find ( buffer_bound ( "Bytes" ) )
112
+ . any ( is_buffer_bound ( "Bytes" ) )
69
113
{
70
114
return Some ( BufferGeneric :: Bytes ( param. clone ( ) ) ) ;
71
115
} ;
72
- if let Some ( _ ) = param
116
+ if param
73
117
. bounds
74
118
. iter ( )
75
119
. filter_map ( trait_bound)
76
- . find ( buffer_bound ( "Buffer" ) )
120
+ . any ( is_buffer_bound ( "Buffer" ) )
77
121
{
78
122
return Some ( BufferGeneric :: UmpOrBytes ( param. clone ( ) ) ) ;
79
123
} ;
80
124
}
81
125
None
82
126
}
83
127
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
+
84
139
pub fn rebuffer_generics ( repr : Representation ) -> TokenStream {
85
140
match repr {
86
141
Representation :: Ump => quote ! {
@@ -146,3 +201,18 @@ pub fn try_rebuffer_generics(repr: Representation) -> TokenStream {
146
201
} ,
147
202
}
148
203
}
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