@@ -220,6 +220,77 @@ fn is_phantom_deser_data(ty: &syn::Type) -> bool {
220
220
false
221
221
}
222
222
223
+ /// Add trait bounds for associated (de)serialization types based on bounds on
224
+ /// type parameters.
225
+ fn add_ser_deser_bounds < T : quote:: ToTokens > (
226
+ derive_input : & DeriveInput ,
227
+ types_with_generics : & [ T ] ,
228
+ where_clause_ser : & mut WhereClause ,
229
+ where_clause_des : & mut WhereClause ,
230
+ ) {
231
+ // If there are bounded type parameters which are fields of the
232
+ // struct, we need to impose the same bounds on the SerType and on
233
+ // the DeserType.
234
+ derive_input. generics . params . iter ( ) . for_each ( |param| {
235
+ if let syn:: GenericParam :: Type ( t) = param {
236
+ let ty = & t. ident ;
237
+
238
+ // We are just interested in types with bounds that are
239
+ // types of fields of the struct.
240
+ //
241
+ // Note that types_with_generics contains also field types
242
+ // *containing* a type parameter, but that just slows down
243
+ // the search.
244
+ if !t. bounds . is_empty ( )
245
+ && types_with_generics
246
+ . iter ( )
247
+ . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) )
248
+ {
249
+ // Add a lifetime so we express bounds on DeserType
250
+ let mut lifetimes = Punctuated :: new ( ) ;
251
+ lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
252
+ attrs : vec ! [ ] ,
253
+ lifetime : syn:: Lifetime :: new (
254
+ "'epserde_desertype" ,
255
+ proc_macro2:: Span :: call_site ( ) ,
256
+ ) ,
257
+ colon_token : None ,
258
+ bounds : Punctuated :: new ( ) ,
259
+ } ) ) ;
260
+
261
+ // Add the type bounds to the DeserType
262
+ where_clause_des
263
+ . predicates
264
+ . push ( WherePredicate :: Type ( PredicateType {
265
+ lifetimes : Some ( BoundLifetimes {
266
+ for_token : token:: For :: default ( ) ,
267
+ lt_token : token:: Lt :: default ( ) ,
268
+ lifetimes,
269
+ gt_token : token:: Gt :: default ( ) ,
270
+ } ) ,
271
+ bounded_ty : syn:: parse_quote!(
272
+ <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
273
+ ) ,
274
+ colon_token : token:: Colon :: default ( ) ,
275
+ bounds : t. bounds . clone ( ) ,
276
+ } ) ) ;
277
+
278
+ // Add the type bounds to the SerType
279
+ where_clause_ser
280
+ . predicates
281
+ . push ( WherePredicate :: Type ( PredicateType {
282
+ lifetimes : None ,
283
+ bounded_ty : syn:: parse_quote!(
284
+ <#ty as epserde:: ser:: SerializeInner >:: SerType
285
+ ) ,
286
+ colon_token : token:: Colon :: default ( ) ,
287
+ bounds : t. bounds . clone ( ) ,
288
+ } ) ) ;
289
+ }
290
+ }
291
+ } ) ;
292
+ }
293
+
223
294
/// Generate an ε-serde implementation for custom types.
224
295
///
225
296
/// It generates implementations for the traits `CopyType`,
@@ -265,7 +336,7 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
265
336
..
266
337
} = CommonDeriveInput :: new ( derive_input. clone ( ) , vec ! [ ] ) ;
267
338
268
- let out = match derive_input. data {
339
+ let out = match & derive_input. data {
269
340
Data :: Struct ( s) => {
270
341
let mut fields_types = vec ! [ ] ;
271
342
let mut fields_names = vec ! [ ] ;
@@ -434,61 +505,12 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
434
505
}
435
506
}
436
507
} else {
437
- // If there are bounded type parameters which are fields of the
438
- // struct, we need to impose the same bounds on the SerType and on
439
- // the DeserType.
440
- derive_input. generics . params . iter ( ) . for_each ( |param| {
441
- if let GenericParam :: Type ( t) = param {
442
- let ty = & t. ident ;
443
-
444
- // We are just interested in types with bounds that are
445
- // types of fields of the struct.
446
- //
447
- // Note that types_with_generics contains also field types
448
- // *containing* a type parameter, but that just slows down
449
- // the search.
450
- if ! t. bounds . is_empty ( ) &&
451
- types_with_generics. iter ( ) . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) ) {
452
-
453
- let mut lifetimes = Punctuated :: new ( ) ;
454
- // Add a lifetime so we express bounds on DeserType
455
- lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
456
- attrs : vec ! [ ] ,
457
- lifetime : syn:: Lifetime :: new ( "'epserde_desertype" , proc_macro2:: Span :: call_site ( ) ) ,
458
- colon_token : None ,
459
- bounds : Punctuated :: new ( ) ,
460
- } ) ) ;
461
- // Add the type bounds to the DeserType
462
- where_clause_des
463
- . predicates
464
- . push ( WherePredicate :: Type ( PredicateType {
465
- lifetimes : Some ( BoundLifetimes {
466
- for_token : token:: For :: default ( ) ,
467
- lt_token : token:: Lt :: default ( ) ,
468
- lifetimes,
469
- gt_token : token:: Gt :: default ( ) ,
470
- } ) ,
471
- bounded_ty : syn:: parse_quote!(
472
- <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
473
- ) ,
474
- colon_token : token:: Colon :: default ( ) ,
475
- bounds : t. bounds . clone ( ) ,
476
- } ) ) ;
477
-
478
- // Add the type bounds to the SerType
479
- where_clause_ser
480
- . predicates
481
- . push ( WherePredicate :: Type ( PredicateType {
482
- lifetimes : None ,
483
- bounded_ty : syn:: parse_quote!(
484
- <#ty as epserde:: ser:: SerializeInner >:: SerType
485
- ) ,
486
- colon_token : token:: Colon :: default ( ) ,
487
- bounds : t. bounds . clone ( ) ,
488
- } ) ) ;
489
- }
490
- }
491
- } ) ;
508
+ add_ser_deser_bounds (
509
+ & derive_input,
510
+ & types_with_generics,
511
+ & mut where_clause_ser,
512
+ & mut where_clause_des,
513
+ ) ;
492
514
493
515
quote ! {
494
516
#[ automatically_derived]
@@ -817,61 +839,12 @@ pub fn epserde_derive(input: TokenStream) -> TokenStream {
817
839
}
818
840
}
819
841
} else {
820
- // If there are bounded type parameters which are fields of the
821
- // struct, we need to impose the same bounds on the SerType and on
822
- // the DeserType.
823
- derive_input. generics . params . iter ( ) . for_each ( |param| {
824
- if let GenericParam :: Type ( t) = param {
825
- let ty = & t. ident ;
826
-
827
- // We are just interested in types with bounds that are
828
- // types of fields of the struct.
829
- //
830
- // Note that types_with_generics contains also field types
831
- // *containing* a type parameter, but that just slows down
832
- // the search.
833
- if ! t. bounds . is_empty ( ) &&
834
- types_with_generics. iter ( ) . any ( |x| * ty == x. to_token_stream ( ) . to_string ( ) ) {
835
-
836
- let mut lifetimes = Punctuated :: new ( ) ;
837
- // Add a lifetime so we express bounds on DeserType
838
- lifetimes. push ( GenericParam :: Lifetime ( LifetimeParam {
839
- attrs : vec ! [ ] ,
840
- lifetime : syn:: Lifetime :: new ( "'epserde_desertype" , proc_macro2:: Span :: call_site ( ) ) ,
841
- colon_token : None ,
842
- bounds : Punctuated :: new ( ) ,
843
- } ) ) ;
844
- // Add the type bounds to the DeserType
845
- where_clause_des
846
- . predicates
847
- . push ( WherePredicate :: Type ( PredicateType {
848
- lifetimes : Some ( BoundLifetimes {
849
- for_token : token:: For :: default ( ) ,
850
- lt_token : token:: Lt :: default ( ) ,
851
- lifetimes,
852
- gt_token : token:: Gt :: default ( ) ,
853
- } ) ,
854
- bounded_ty : syn:: parse_quote!(
855
- <#ty as epserde:: deser:: DeserializeInner >:: DeserType <' epserde_desertype>
856
- ) ,
857
- colon_token : token:: Colon :: default ( ) ,
858
- bounds : t. bounds . clone ( ) ,
859
- } ) ) ;
860
-
861
- // Add the type bounds to the SerType
862
- where_clause_ser
863
- . predicates
864
- . push ( WherePredicate :: Type ( PredicateType {
865
- lifetimes : None ,
866
- bounded_ty : syn:: parse_quote!(
867
- <#ty as epserde:: ser:: SerializeInner >:: SerType
868
- ) ,
869
- colon_token : token:: Colon :: default ( ) ,
870
- bounds : t. bounds . clone ( ) ,
871
- } ) ) ;
872
- }
873
- }
874
- } ) ;
842
+ add_ser_deser_bounds (
843
+ & derive_input,
844
+ & types_with_generics,
845
+ & mut where_clause_ser,
846
+ & mut where_clause_des,
847
+ ) ;
875
848
876
849
quote ! {
877
850
#[ automatically_derived]
0 commit comments