@@ -198,120 +198,107 @@ fn impl_gdnative_expose(ast: ItemImpl) -> (ItemImpl, ClassMethodExport) {
198
198
199
199
if let Some ( "export" ) = last_seg. as_deref ( ) {
200
200
let _export_args = export_args. get_or_insert_with ( ExportArgs :: default) ;
201
- if !attr. tokens . is_empty ( ) {
202
- use syn:: { Meta , MetaNameValue , NestedMeta } ;
203
-
204
- let meta = match attr. parse_meta ( ) {
205
- Ok ( val) => val,
201
+ use syn:: { punctuated:: Punctuated , Lit , Meta , NestedMeta } ;
202
+ let nested_meta_iter = match attr. parse_meta ( ) {
206
203
Err ( err) => {
207
204
errors. push ( err) ;
208
205
return false ;
209
206
}
210
- } ;
211
-
212
- let pairs: Vec < _ > = match meta {
213
- Meta :: List ( list) => list
214
- . nested
215
- . into_pairs ( )
216
- . filter_map ( |p| {
217
- let span = p. span ( ) ;
218
- match p. into_value ( ) {
219
- NestedMeta :: Meta ( Meta :: NameValue ( pair) ) => {
220
- Some ( pair)
221
- }
222
- unexpected => {
223
- let msg = format ! (
224
- "unexpected argument in list: {}" ,
225
- unexpected. into_token_stream( )
226
- ) ;
207
+ Ok ( Meta :: NameValue ( name_value) ) => {
208
+ let span = name_value. span ( ) ;
209
+ let msg = "NameValue syntax is not valid" ;
227
210
errors. push ( syn:: Error :: new ( span, msg) ) ;
228
- None
211
+ return false ;
229
212
}
213
+ Ok ( Meta :: Path ( _) ) => {
214
+ Punctuated :: < NestedMeta , syn:: token:: Comma > :: new ( ) . into_iter ( )
230
215
}
231
- } )
232
- . collect ( ) ,
233
- Meta :: NameValue ( pair) => vec ! [ pair] ,
234
- meta => {
235
- let span = meta. span ( ) ;
236
- let msg = format ! (
237
- "unexpected attribute argument: {}" ,
238
- meta. into_token_stream( )
239
- ) ;
216
+ Ok ( Meta :: List ( list) ) => list. nested . into_iter ( ) ,
217
+ } ;
218
+ for nested_meta in nested_meta_iter {
219
+ let ( path, lit) = match & nested_meta {
220
+ NestedMeta :: Lit ( param) => {
221
+ let span = param. span ( ) ;
222
+ let msg = "Literal item is not valid" ;
240
223
errors. push ( syn:: Error :: new ( span, msg) ) ;
241
- return false ;
224
+ continue ;
242
225
}
243
- } ;
244
-
245
- for MetaNameValue { path, lit, .. } in pairs {
246
- let last = match path. segments . last ( ) {
247
- Some ( val) => val,
248
- None => {
249
- errors. push ( syn:: Error :: new (
250
- path. span ( ) ,
251
- "the path should not be empty" ,
252
- ) ) ;
253
- return false ;
226
+ NestedMeta :: Meta ( param) => match param {
227
+ Meta :: List ( list) => {
228
+ let span = list. span ( ) ;
229
+ let msg = "List item is not valid" ;
230
+ errors. push ( syn:: Error :: new ( span, msg) ) ;
231
+ continue ;
254
232
}
233
+ Meta :: Path ( path) => ( path, None ) ,
234
+ Meta :: NameValue ( name_value) => {
235
+ ( & name_value. path , Some ( & name_value. lit ) )
236
+ }
237
+ } ,
255
238
} ;
256
- let path = last. ident . to_string ( ) ;
257
-
258
- // Match optional export arguments
259
- match path. as_str ( ) {
239
+ if path. is_ident ( "rpc" ) {
260
240
// rpc mode
261
- "rpc" => {
262
- let value = if let syn:: Lit :: Str ( lit_str) = lit {
263
- lit_str. value ( )
264
- } else {
241
+ match lit {
242
+ None => {
265
243
errors. push ( syn:: Error :: new (
266
- last . span ( ) ,
267
- "unexpected type for rpc value, expected Str ",
244
+ nested_meta . span ( ) ,
245
+ "name parameter requires string value",
268
246
) ) ;
269
- return false ;
270
- } ;
271
-
247
+ }
248
+ Some ( Lit :: Str ( str ) ) => {
249
+ let value = str . value ( ) ;
272
250
if let Some ( mode) = RpcMode :: parse ( value. as_str ( ) ) {
273
251
if rpc. replace ( mode) . is_some ( ) {
274
252
errors. push ( syn:: Error :: new (
275
- last . span ( ) ,
253
+ nested_meta . span ( ) ,
276
254
"rpc mode was set more than once" ,
277
255
) ) ;
278
- return false ;
279
256
}
280
257
} else {
281
258
errors. push ( syn:: Error :: new (
282
- last . span ( ) ,
259
+ nested_meta . span ( ) ,
283
260
format ! ( "unexpected value for rpc: {}" , value) ,
284
261
) ) ;
285
- return false ;
286
262
}
287
263
}
264
+ _ => {
265
+ errors. push ( syn:: Error :: new (
266
+ nested_meta. span ( ) ,
267
+ "unexpected type for rpc value, expected string" ,
268
+ ) ) ;
269
+ }
270
+ }
271
+ } else if path. is_ident ( "name" ) {
288
272
// name override
289
- "name" => {
290
- let value = if let syn:: Lit :: Str ( lit_str) = lit {
291
- lit_str. value ( )
292
- } else {
273
+ match lit {
274
+ None => {
293
275
errors. push ( syn:: Error :: new (
294
- last . span ( ) ,
295
- "unexpected type for name value, expected Str ",
276
+ nested_meta . span ( ) ,
277
+ "name parameter requires string value",
296
278
) ) ;
297
- return false ;
298
- } ;
299
-
300
- if name_override. replace ( value) . is_some ( ) {
279
+ }
280
+ Some ( Lit :: Str ( str) ) => {
281
+ if name_override. replace ( str. value ( ) ) . is_some ( ) {
301
282
errors. push ( syn:: Error :: new (
302
- last . span ( ) ,
283
+ nested_meta . span ( ) ,
303
284
"name was set more than once" ,
304
285
) ) ;
305
- return false ;
306
286
}
307
287
}
308
288
_ => {
309
- let msg =
310
- format ! ( "unknown option for export: `{}`" , path ) ;
311
- errors . push ( syn :: Error :: new ( last . span ( ) , msg ) ) ;
312
- return false ;
289
+ errors . push ( syn :: Error :: new (
290
+ nested_meta . span ( ) ,
291
+ "unexpected type for name value, expected string" ,
292
+ ) ) ;
313
293
}
314
294
}
295
+ }
296
+ } else {
297
+ let msg = format ! (
298
+ "unknown option for export: `{}`" ,
299
+ path. to_token_stream( )
300
+ ) ;
301
+ errors. push ( syn:: Error :: new ( nested_meta. span ( ) , msg) ) ;
315
302
}
316
303
}
317
304
return false ;
0 commit comments