@@ -96,7 +96,7 @@ extern crate quote;
96
96
97
97
use proc_macro:: { TokenStream } ;
98
98
use proc_macro2:: { TokenStream as TokenStream2 , Span } ;
99
- use syn:: { * , punctuated :: Punctuated , token :: Where } ;
99
+ use syn:: * ;
100
100
type SynStream = TokenStream2 ;
101
101
102
102
// Debugging:
@@ -163,31 +163,43 @@ impl FieldAttrs {
163
163
}
164
164
fn parse ( list : & [ Attribute ] ) -> FieldAttrs {
165
165
let mut attrs = FieldAttrs :: new ( ) ;
166
- for attr in list. iter ( ) . filter ( |attr| attr. path . is_ident ( "pdf" ) ) {
167
- let list = match attr. parse_meta ( ) {
168
- Ok ( Meta :: List ( list) ) => list,
169
- Ok ( _) => panic ! ( "only #[pdf(attrs...)] is allowed" ) ,
170
- Err ( e) => panic ! ( "can't parse meta attributes: {}" , e)
171
- } ;
172
- for meta in list. nested . iter ( ) {
173
- match * meta {
174
- NestedMeta :: Meta ( Meta :: NameValue ( MetaNameValue { ref path, lit : Lit :: Str ( ref value) , ..} ) ) => {
175
- if path. is_ident ( "key" ) {
176
- attrs. key = Some ( value. clone ( ) ) ;
177
- } else if path. is_ident ( "default" ) {
178
- attrs. default = Some ( value. clone ( ) ) ;
179
- } else if path. is_ident ( "name" ) {
180
- attrs. name = Some ( value. clone ( ) ) ;
181
- } else {
182
- panic ! ( "unsupported key {}" , path. segments. iter( ) . map( |s| s. ident. to_string( ) ) . collect:: <Vec <String >>( ) . join( "::" ) )
183
- }
184
- } ,
185
- NestedMeta :: Meta ( Meta :: Path ( ref path) ) if path. is_ident ( "skip" ) => attrs. skip = true ,
186
- NestedMeta :: Meta ( Meta :: Path ( ref path) ) if path. is_ident ( "other" ) => attrs. other = true ,
187
- NestedMeta :: Meta ( Meta :: Path ( ref path) ) if path. is_ident ( "indirect" ) => attrs. indirect = true ,
188
- _ => panic ! ( r#"Derive error - Supported derive attributes: `key="Key"`, `default="some code", skip, other, indirect`."# )
166
+ for attr in list. iter ( ) . filter ( |attr| attr. path ( ) . is_ident ( "pdf" ) ) {
167
+ attr. parse_nested_meta ( |meta| {
168
+ if meta. path . is_ident ( "key" ) {
169
+ let value = meta. value ( ) ?;
170
+ attrs. key = Some ( value. parse ( ) ?) ;
171
+ return Ok ( ( ) ) ;
189
172
}
190
- }
173
+
174
+ if meta. path . is_ident ( "default" ) {
175
+ let value = meta. value ( ) ?;
176
+ attrs. default = Some ( value. parse ( ) ?) ;
177
+ return Ok ( ( ) ) ;
178
+ }
179
+
180
+ if meta. path . is_ident ( "name" ) {
181
+ let value = meta. value ( ) ?;
182
+ attrs. name = Some ( value. parse ( ) ?) ;
183
+ return Ok ( ( ) ) ;
184
+ }
185
+
186
+ if meta. path . is_ident ( "skip" ) {
187
+ attrs. skip = true ;
188
+ return Ok ( ( ) ) ;
189
+ }
190
+
191
+ if meta. path . is_ident ( "other" ) {
192
+ attrs. other = true ;
193
+ return Ok ( ( ) ) ;
194
+ }
195
+
196
+ if meta. path . is_ident ( "indirect" ) {
197
+ attrs. indirect = true ;
198
+ return Ok ( ( ) ) ;
199
+ }
200
+
201
+ Err ( meta. error ( "unsupported key" ) )
202
+ } ) . expect ( "parse error" ) ;
191
203
}
192
204
attrs
193
205
}
@@ -209,42 +221,51 @@ impl GlobalAttrs {
209
221
fn from_ast ( ast : & DeriveInput ) -> GlobalAttrs {
210
222
let mut attrs = GlobalAttrs :: default ( ) ;
211
223
212
- for attr in ast. attrs . iter ( ) . filter ( |attr| attr. path . is_ident ( "pdf" ) ) {
213
- let list = match attr. parse_meta ( ) {
214
- Ok ( Meta :: List ( list) ) => list,
215
- Ok ( _) => panic ! ( "only #[pdf(attrs...)] is allowed" ) ,
216
- Err ( e) => panic ! ( "can't parse meta attributes: {}" , e)
217
- } ;
224
+ for attr in ast. attrs . iter ( ) . filter ( |attr| attr. path ( ) . is_ident ( "pdf" ) ) {
225
+ attr. parse_nested_meta ( |meta| {
226
+ if meta. path . is_ident ( "Type" ) {
227
+ let value = meta. value ( ) ?;
228
+ let lit = value. parse ( ) ?;
229
+ match lit {
230
+ Lit :: Str ( ref value) => {
231
+ let mut value = value. value ( ) ;
232
+ attrs. type_required = if value. ends_with ( '?' ) {
233
+ value. pop ( ) ; // remove '?'
234
+ false
235
+ } else {
236
+ true
237
+ } ;
238
+ attrs. type_name = Some ( value) ;
239
+ } ,
240
+ _ => panic ! ( "Value of 'Type' attribute must be a String." ) ,
241
+ } ;
242
+ return Ok ( ( ) )
243
+ }
218
244
219
- // Loop through list of attributes
220
- for meta in list. nested . iter ( ) {
221
- match * meta {
222
- NestedMeta :: Meta ( Meta :: NameValue ( MetaNameValue { ref path, ref lit, ..} ) ) => {
223
- if path. is_ident ( "Type" ) {
224
- match lit {
225
- Lit :: Str ( ref value) => {
226
- let mut value = value. value ( ) ;
227
- attrs. type_required = if value. ends_with ( '?' ) {
228
- value. pop ( ) ; // remove '?'
229
- false
230
- } else {
231
- true
232
- } ;
233
- attrs. type_name = Some ( value) ;
234
- } ,
235
- _ => panic ! ( "Value of 'Type' attribute must be a String." ) ,
236
- }
237
- } else {
238
- match lit {
239
- Lit :: Str ( ref value) => attrs. checks . push ( ( path. segments . iter ( ) . map ( |s| s. ident . to_string ( ) ) . collect :: < Vec < String > > ( ) . join ( "::" ) , value. value ( ) ) ) ,
240
- _ => panic ! ( "Other checks must have RHS String." ) ,
241
- }
245
+ if meta. path . is_ident ( "is_stream" ) {
246
+ attrs. is_stream = true ;
247
+ return Ok ( ( ) )
248
+ }
249
+
250
+ if let Ok ( value) = meta. value ( ) {
251
+ let path = & meta. path ;
252
+ let lit = value. parse ( ) ?;
253
+ match lit {
254
+ Lit :: Str ( ref value) => {
255
+ let segments = path. segments
256
+ . iter ( )
257
+ . map ( |s| s. ident . to_string ( ) )
258
+ . collect :: < Vec < String > > ( )
259
+ . join ( "::" ) ;
260
+ attrs. checks . push ( ( segments, value. value ( ) ) ) ;
242
261
}
243
- } ,
244
- NestedMeta :: Meta ( Meta :: Path ( ref path ) ) if path . is_ident ( "is_stream" ) => attrs . is_stream = true ,
245
- _ => { }
262
+ _ => panic ! ( "Other checks must have RHS String." ) ,
263
+ } ;
264
+ return Ok ( ( ) )
246
265
}
247
- }
266
+
267
+ Ok ( ( ) )
268
+ } ) . expect ( "error with global attrs parsing" ) ;
248
269
}
249
270
250
271
attrs
@@ -322,9 +343,9 @@ fn impl_object_for_enum(ast: &DeriveInput, data: &DataEnum) -> SynStream {
322
343
assert_eq ! ( int_count, data. variants. len( ) , "either none or all variants can have a descriminant" ) ;
323
344
324
345
let parts = data. variants . iter ( ) . map ( |var| {
325
- if let Some ( ( _, ref expr ) ) = var. discriminant {
346
+ if let Some ( ( _, Expr :: Lit ( ref lit_expr ) ) ) = var. discriminant {
326
347
let var_ident = & var. ident ;
327
- let pat = Pat :: Lit ( PatLit { expr : Box :: new ( expr . clone ( ) ) , attrs : vec ! [ ] } ) ;
348
+ let pat = Pat :: from ( lit_expr . clone ( ) ) ;
328
349
quote ! {
329
350
#pat => Ok ( #id:: #var_ident)
330
351
}
0 commit comments