@@ -37,6 +37,7 @@ fn derive_variant_for_struct(
37
37
data_struct : syn:: DataStruct ,
38
38
) -> TokenStream {
39
39
let glib = crate_ident_new ( ) ;
40
+ let ( impl_generics, type_generics, where_clause) = generics. split_for_impl ( ) ;
40
41
let ( static_variant_type, to_variant, from_variant) = match data_struct. fields {
41
42
Fields :: Unnamed ( FieldsUnnamed { unnamed, .. } ) => {
42
43
let types = unnamed
@@ -49,7 +50,7 @@ fn derive_variant_for_struct(
49
50
let idents_len = idents. len ( ) ;
50
51
51
52
let static_variant_type = quote ! {
52
- impl #generics #glib:: StaticVariantType for #ident #generics {
53
+ impl #impl_generics #glib:: StaticVariantType for #ident #type_generics #where_clause {
53
54
fn static_variant_type( ) -> :: std:: borrow:: Cow <' static , #glib:: VariantTy > {
54
55
static TYP : #glib:: once_cell:: sync:: Lazy <#glib:: VariantType > = #glib:: once_cell:: sync:: Lazy :: new( || {
55
56
@@ -72,7 +73,7 @@ fn derive_variant_for_struct(
72
73
} ;
73
74
74
75
let to_variant = quote ! {
75
- impl #generics #glib:: ToVariant for #ident #generics {
76
+ impl #impl_generics #glib:: ToVariant for #ident #type_generics #where_clause {
76
77
fn to_variant( & self ) -> #glib:: Variant {
77
78
#glib:: Variant :: tuple_from_iter( :: std:: array:: IntoIter :: <#glib:: Variant , #idents_len>:: new( [
78
79
#(
@@ -81,10 +82,20 @@ fn derive_variant_for_struct(
81
82
] ) )
82
83
}
83
84
}
85
+
86
+ impl #impl_generics :: std:: convert:: From <#ident #type_generics> for #glib:: Variant #where_clause {
87
+ fn from( v: #ident #type_generics) -> #glib:: Variant {
88
+ #glib:: Variant :: tuple_from_iter( :: std:: array:: IntoIter :: <#glib:: Variant , #idents_len>:: new( [
89
+ #(
90
+ <#glib:: Variant as :: std:: convert:: From <_>>:: from( v. #idents)
91
+ ) , *
92
+ ] ) )
93
+ }
94
+ }
84
95
} ;
85
96
86
97
let from_variant = quote ! {
87
- impl #generics #glib:: FromVariant for #ident #generics {
98
+ impl #impl_generics #glib:: FromVariant for #ident #type_generics #where_clause {
88
99
fn from_variant( variant: & #glib:: Variant ) -> :: core:: option:: Option <Self > {
89
100
if !variant. is_container( ) {
90
101
return None ;
@@ -115,7 +126,7 @@ fn derive_variant_for_struct(
115
126
let counts = ( 0 ..types. len ( ) ) . map ( syn:: Index :: from) . collect :: < Vec < _ > > ( ) ;
116
127
117
128
let static_variant_type = quote ! {
118
- impl #generics #glib:: StaticVariantType for #ident #generics {
129
+ impl #impl_generics #glib:: StaticVariantType for #ident #type_generics #where_clause {
119
130
fn static_variant_type( ) -> :: std:: borrow:: Cow <' static , #glib:: VariantTy > {
120
131
static TYP : #glib:: once_cell:: sync:: Lazy <#glib:: VariantType > = #glib:: once_cell:: sync:: Lazy :: new( || unsafe {
121
132
let ptr = #glib:: ffi:: g_string_sized_new( 16 ) ;
@@ -144,7 +155,7 @@ fn derive_variant_for_struct(
144
155
} ;
145
156
146
157
let to_variant = quote ! {
147
- impl #generics #glib:: ToVariant for #ident #generics {
158
+ impl #impl_generics #glib:: ToVariant for #ident #type_generics #where_clause {
148
159
fn to_variant( & self ) -> #glib:: Variant {
149
160
#glib:: Variant :: tuple_from_iter( :: std:: iter:: IntoIterator :: into_iter( [
150
161
#(
@@ -153,10 +164,20 @@ fn derive_variant_for_struct(
153
164
] ) )
154
165
}
155
166
}
167
+
168
+ impl #impl_generics :: std:: convert:: From <#ident #type_generics> for #glib:: Variant #where_clause {
169
+ fn from( v: #ident #type_generics) -> #glib:: Variant {
170
+ #glib:: Variant :: tuple_from_iter( :: std:: iter:: IntoIterator :: into_iter( [
171
+ #(
172
+ <#glib:: Variant as :: std:: convert:: From <_>>:: from( v. #idents)
173
+ ) , *
174
+ ] ) )
175
+ }
176
+ }
156
177
} ;
157
178
158
179
let from_variant = quote ! {
159
- impl #generics #glib:: FromVariant for #ident #generics {
180
+ impl #impl_generics #glib:: FromVariant for #ident #type_generics #where_clause {
160
181
fn from_variant( variant: & #glib:: Variant ) -> :: core:: option:: Option <Self > {
161
182
if !variant. is_container( ) {
162
183
return None ;
@@ -177,23 +198,32 @@ fn derive_variant_for_struct(
177
198
}
178
199
Fields :: Unit => {
179
200
let static_variant_type = quote ! {
180
- impl #generics #glib:: StaticVariantType for #ident #generics {
201
+ impl #impl_generics #glib:: StaticVariantType for #ident #type_generics #where_clause {
202
+ #[ inline]
181
203
fn static_variant_type( ) -> :: std:: borrow:: Cow <' static , #glib:: VariantTy > {
182
204
:: std:: borrow:: Cow :: Borrowed ( #glib:: VariantTy :: UNIT )
183
205
}
184
206
}
185
207
} ;
186
208
187
209
let to_variant = quote ! {
188
- impl #generics #glib:: ToVariant for #ident #generics {
210
+ impl #impl_generics #glib:: ToVariant for #ident #type_generics #where_clause {
211
+ #[ inline]
189
212
fn to_variant( & self ) -> #glib:: Variant {
190
213
#glib:: ToVariant :: to_variant( & ( ) )
191
214
}
192
215
}
216
+
217
+ impl #impl_generics :: std:: convert:: From <#ident #type_generics> for #glib:: Variant #where_clause {
218
+ #[ inline]
219
+ fn from( v: #ident #type_generics) -> #glib:: Variant {
220
+ #glib:: ToVariant :: to_variant( & ( ) )
221
+ }
222
+ }
193
223
} ;
194
224
195
225
let from_variant = quote ! {
196
- impl #generics #glib:: FromVariant for #ident #generics {
226
+ impl #impl_generics #glib:: FromVariant for #ident #type_generics #where_clause {
197
227
fn from_variant( variant: & #glib:: Variant ) -> :: core:: option:: Option <Self > {
198
228
Some ( Self )
199
229
}
@@ -262,6 +292,7 @@ fn derive_variant_for_enum(
262
292
) -> TokenStream {
263
293
let glib = crate_ident_new ( ) ;
264
294
let static_variant_type = format ! ( "({}v)" , mode. tag_type( ) ) ;
295
+ let ( impl_generics, type_generics, where_clause) = generics. split_for_impl ( ) ;
265
296
266
297
let to = data_enum. variants . iter ( ) . enumerate ( ) . map ( |( index, v) | {
267
298
let ident = & v. ident ;
@@ -319,6 +350,54 @@ fn derive_variant_for_enum(
319
350
} ,
320
351
}
321
352
} ) ;
353
+ let into = data_enum. variants . iter ( ) . enumerate ( ) . map ( |( index, v) | {
354
+ let field_ident = & v. ident ;
355
+ let tag = match & mode {
356
+ EnumMode :: String => {
357
+ let nick = ToKebabCase :: to_kebab_case ( field_ident. to_string ( ) . as_str ( ) ) ;
358
+ quote ! { #nick }
359
+ }
360
+ EnumMode :: Repr ( repr) => quote ! { #index as #repr } ,
361
+ _ => unimplemented ! ( ) ,
362
+ } ;
363
+ match & v. fields {
364
+ syn:: Fields :: Named ( FieldsNamed { named, .. } ) => {
365
+ let field_names = named. iter ( ) . map ( |f| f. ident . as_ref ( ) . unwrap ( ) ) ;
366
+ let field_names2 = field_names. clone ( ) ;
367
+ quote ! {
368
+ #ident:: #field_ident { #( #field_names) , * } => #glib:: ToVariant :: to_variant( & (
369
+ #tag,
370
+ #glib:: Variant :: tuple_from_iter( :: std:: iter:: IntoIterator :: into_iter( [
371
+ #( <#glib:: Variant as :: std:: convert:: From <_>>:: from( #field_names2) ) , *
372
+ ] ) )
373
+ ) )
374
+ }
375
+ }
376
+ syn:: Fields :: Unnamed ( FieldsUnnamed { unnamed, .. } ) => {
377
+ let field_names = unnamed
378
+ . iter ( )
379
+ . enumerate ( )
380
+ . map ( |( i, _) | format_ident ! ( "field{}" , i) ) ;
381
+ let field_names2 = field_names. clone ( ) ;
382
+ quote ! {
383
+ #ident:: #field_ident( #( #field_names) , * ) => #glib:: ToVariant :: to_variant( & (
384
+ #tag,
385
+ #glib:: Variant :: tuple_from_iter( :: std:: iter:: IntoIterator :: into_iter( [
386
+ #( <#glib:: Variant as :: std:: convert:: From <_>>:: from( #field_names2) ) , *
387
+ ] ) )
388
+ ) )
389
+ }
390
+ }
391
+ syn:: Fields :: Unit => {
392
+ quote ! {
393
+ #ident:: #field_ident => #glib:: ToVariant :: to_variant( & (
394
+ #tag,
395
+ #glib:: ToVariant :: to_variant( & ( ) )
396
+ ) )
397
+ }
398
+ }
399
+ }
400
+ } ) ;
322
401
let from = data_enum. variants . iter ( ) . enumerate ( ) . map ( |( index, v) | {
323
402
let ident = & v. ident ;
324
403
let tag = match & mode {
@@ -368,7 +447,7 @@ fn derive_variant_for_enum(
368
447
} ;
369
448
370
449
let derived = quote ! {
371
- impl #generics #glib:: StaticVariantType for #ident #generics {
450
+ impl #impl_generics #glib:: StaticVariantType for #ident #type_generics #where_clause {
372
451
fn static_variant_type( ) -> :: std:: borrow:: Cow <' static , #glib:: VariantTy > {
373
452
:: std:: borrow:: Cow :: Borrowed (
374
453
unsafe {
@@ -378,15 +457,23 @@ fn derive_variant_for_enum(
378
457
}
379
458
}
380
459
381
- impl #generics #glib:: ToVariant for #ident #generics {
460
+ impl #impl_generics #glib:: ToVariant for #ident #type_generics #where_clause {
382
461
fn to_variant( & self ) -> #glib:: Variant {
383
462
match self {
384
463
#( #to) , *
385
464
}
386
465
}
387
466
}
388
467
389
- impl #generics #glib:: FromVariant for #ident #generics {
468
+ impl #impl_generics :: std:: convert:: From <#ident #type_generics> for #glib:: Variant #where_clause {
469
+ fn from( v: #ident #type_generics) -> #glib:: Variant {
470
+ match v {
471
+ #( #into) , *
472
+ }
473
+ }
474
+ }
475
+
476
+ impl #impl_generics #glib:: FromVariant for #ident #type_generics #where_clause {
390
477
fn from_variant( variant: & #glib:: Variant ) -> :: std:: option:: Option <Self > {
391
478
let ( tag, value) = <( #repr, #glib:: Variant ) as #glib:: FromVariant >:: from_variant( & variant) ?;
392
479
if !#glib:: VariantTy :: is_tuple( #glib:: Variant :: type_( & value) ) {
@@ -410,6 +497,7 @@ fn derive_variant_for_c_enum(
410
497
) -> TokenStream {
411
498
let glib = crate_ident_new ( ) ;
412
499
let static_variant_type = mode. tag_type ( ) . to_string ( ) ;
500
+ let ( impl_generics, type_generics, where_clause) = generics. split_for_impl ( ) ;
413
501
414
502
let ( to_variant, from_variant) = match mode {
415
503
EnumMode :: String => {
@@ -508,7 +596,7 @@ fn derive_variant_for_c_enum(
508
596
} ;
509
597
510
598
let derived = quote ! {
511
- impl #generics #glib:: StaticVariantType for #ident #generics {
599
+ impl #impl_generics #glib:: StaticVariantType for #ident #type_generics #where_clause {
512
600
fn static_variant_type( ) -> :: std:: borrow:: Cow <' static , #glib:: VariantTy > {
513
601
:: std:: borrow:: Cow :: Borrowed (
514
602
unsafe {
@@ -518,13 +606,20 @@ fn derive_variant_for_c_enum(
518
606
}
519
607
}
520
608
521
- impl #generics #glib:: ToVariant for #ident #generics {
609
+ impl #impl_generics #glib:: ToVariant for #ident #type_generics #where_clause {
522
610
fn to_variant( & self ) -> #glib:: Variant {
523
611
#to_variant
524
612
}
525
613
}
526
614
527
- impl #generics #glib:: FromVariant for #ident #generics {
615
+ impl #impl_generics :: std:: convert:: From <#ident #type_generics> for #glib:: Variant #where_clause {
616
+ #[ inline]
617
+ fn from( v: #ident #type_generics) -> #glib:: Variant {
618
+ <#ident #type_generics as #glib:: ToVariant >:: to_variant( & v)
619
+ }
620
+ }
621
+
622
+ impl #impl_generics #glib:: FromVariant for #ident #type_generics #where_clause {
528
623
fn from_variant( variant: & #glib:: Variant ) -> :: std:: option:: Option <Self > {
529
624
#from_variant
530
625
}
0 commit comments