@@ -17,9 +17,11 @@ use std::path::{Path, PathBuf};
17
17
use std:: { env, fs} ;
18
18
19
19
use itertools:: Itertools ;
20
+ use proc_macro2:: TokenTree ;
20
21
use quote:: ToTokens ;
21
22
use serde:: Serialize ;
22
- use syn:: { parse_file, Attribute , Field , Item , ItemFn , Lit , Meta , MetaNameValue , NestedMeta , Type } ;
23
+ use syn:: { parse_file, Attribute , Field , Item , ItemFn , Lit , LitStr , Meta , Type } ;
24
+ use thiserror_ext:: AsReport ;
23
25
use walkdir:: { DirEntry , WalkDir } ;
24
26
25
27
fn connector_crate_path ( ) -> PathBuf {
@@ -216,16 +218,14 @@ struct FunctionInfo {
216
218
/// Has `#[derive(WithOptions)]`
217
219
fn has_with_options_attribute ( attrs : & [ Attribute ] ) -> bool {
218
220
attrs. iter ( ) . any ( |attr| {
219
- if let Ok ( Meta :: List ( meta_list) ) = attr. parse_meta ( ) {
221
+ if let Meta :: List ( meta_list) = & attr. meta {
220
222
return meta_list. path . is_ident ( "derive" )
221
- && meta_list. nested . iter ( ) . any ( |nested| match nested {
222
- syn:: NestedMeta :: Meta ( Meta :: Path ( path) ) => {
223
- // Check if the path contains WithOptions
224
- path. segments
225
- . iter ( )
226
- . any ( |segment| segment. ident == "WithOptions" )
223
+ && meta_list. tokens . clone ( ) . into_iter ( ) . any ( |token| {
224
+ if let TokenTree :: Ident ( ident) = token {
225
+ ident == "WithOptions"
226
+ } else {
227
+ false
227
228
}
228
- _ => false ,
229
229
} ) ;
230
230
}
231
231
false
@@ -236,9 +236,13 @@ fn extract_comments(attrs: &[Attribute]) -> String {
236
236
attrs
237
237
. iter ( )
238
238
. filter_map ( |attr| {
239
- if let Ok ( Meta :: NameValue ( mnv) ) = attr. parse_meta ( ) {
239
+ if let Meta :: NameValue ( mnv) = & attr. meta {
240
240
if mnv. path . is_ident ( "doc" ) {
241
- if let syn:: Lit :: Str ( lit_str) = mnv. lit {
241
+ if let syn:: Expr :: Lit ( syn:: ExprLit {
242
+ lit : Lit :: Str ( lit_str) ,
243
+ ..
244
+ } ) = & mnv. value
245
+ {
242
246
return Some ( lit_str. value ( ) . trim ( ) . to_string ( ) ) ;
243
247
}
244
248
}
@@ -253,38 +257,43 @@ fn extract_comments(attrs: &[Attribute]) -> String {
253
257
254
258
fn extract_serde_properties ( field : & Field ) -> SerdeProperties {
255
259
for attr in & field. attrs {
256
- if let Ok ( meta ) = attr. parse_meta ( ) {
257
- if meta . path ( ) . is_ident ( "serde" ) {
260
+ if let Meta :: List ( meta_list ) = & attr. meta {
261
+ if meta_list . path . is_ident ( "serde" ) {
258
262
// Initialize the values to be extracted
259
263
let mut serde_props = SerdeProperties :: default ( ) ;
260
264
261
- if let Meta :: List ( meta_list) = meta {
262
- // Iterate over nested meta items (e.g., rename = "abc")
263
- for nested_meta in meta_list. nested {
264
- if let NestedMeta :: Meta ( Meta :: NameValue ( MetaNameValue {
265
- path, lit, ..
266
- } ) ) = nested_meta
267
- {
268
- if path. is_ident ( "rename" ) {
269
- if let Lit :: Str ( lit_str) = lit {
270
- serde_props. rename = Some ( lit_str. value ( ) ) ;
271
- }
272
- } else if path. is_ident ( "alias" ) {
273
- if let Lit :: Str ( lit_str) = lit {
274
- serde_props. alias . push ( lit_str. value ( ) ) ;
275
- }
276
- } else if path. is_ident ( "default" ) {
277
- if let Lit :: Str ( lit_str) = lit {
278
- serde_props. default_func = Some ( lit_str. value ( ) ) ;
279
- }
265
+ // Iterate over nested meta items (e.g., rename = "abc")
266
+ meta_list
267
+ . parse_nested_meta ( |meta| {
268
+ if meta. path . is_ident ( "rename" ) {
269
+ if let Ok ( value) = meta. value ( ) ?. parse :: < LitStr > ( ) {
270
+ serde_props. rename = Some ( value. value ( ) ) ;
280
271
}
281
- } else if let NestedMeta :: Meta ( Meta :: Path ( path) ) = nested_meta {
282
- if path. is_ident ( "default" ) {
272
+ } else if meta. path . is_ident ( "alias" ) {
273
+ if let Ok ( value) = meta. value ( ) ?. parse :: < LitStr > ( ) {
274
+ serde_props. alias . push ( value. value ( ) ) ;
275
+ }
276
+ } else if meta. path . is_ident ( "default" ) {
277
+ if let Ok ( value) = meta. value ( ) . and_then ( |v| v. parse :: < LitStr > ( ) ) {
278
+ serde_props. default_func = Some ( value. value ( ) ) ;
279
+ } else {
283
280
serde_props. default_func = Some ( "Default::default" . to_string ( ) ) ;
284
281
}
285
282
}
286
- }
287
- }
283
+ // drain the remaining meta. Otherwise parse_nested_meta returns err
284
+ // <https://github.com/dtolnay/syn/issues/1426>
285
+ _ = meta. value ( ) ;
286
+ _ = meta. input . parse :: < LitStr > ( ) ;
287
+ Ok ( ( ) )
288
+ } )
289
+ . unwrap_or_else ( |err| {
290
+ panic ! (
291
+ "Failed to parse serde properties for field: {:?}, err: {}" ,
292
+ field. ident,
293
+ err. to_report_string( ) ,
294
+ )
295
+ } ) ;
296
+
288
297
// Return the extracted values
289
298
return serde_props;
290
299
}
0 commit comments