@@ -14,13 +14,36 @@ use syn::spanned::Spanned;
14
14
use syn:: Token ;
15
15
16
16
pub struct PropsMacroInput {
17
+ wrapper_ty : syn:: Path ,
17
18
ident : syn:: Ident ,
18
19
props : Vec < PropDesc > ,
19
20
}
20
21
22
+ pub struct PropertiesAttr {
23
+ _wrapper_ty_token : syn:: Ident ,
24
+ _eq : Token ! [ =] ,
25
+ wrapper_ty : syn:: Path ,
26
+ }
27
+
28
+ impl Parse for PropertiesAttr {
29
+ fn parse ( input : syn:: parse:: ParseStream ) -> syn:: Result < Self > {
30
+ Ok ( Self {
31
+ _wrapper_ty_token : input. parse ( ) ?,
32
+ _eq : input. parse ( ) ?,
33
+ wrapper_ty : input. parse ( ) ?,
34
+ } )
35
+ }
36
+ }
37
+
21
38
impl Parse for PropsMacroInput {
22
39
fn parse ( input : syn:: parse:: ParseStream ) -> syn:: Result < Self > {
23
40
let derive_input: syn:: DeriveInput = input. parse ( ) ?;
41
+ let wrapper_ty = derive_input
42
+ . attrs
43
+ . iter ( )
44
+ . find ( |x| x. path . is_ident ( "properties" ) )
45
+ . expect ( "missing #[properties(wrapper_type = ...)]" ) ;
46
+ let wrapper_ty: PropertiesAttr = wrapper_ty. parse_args ( ) ?;
24
47
let props: Vec < _ > = match derive_input. data {
25
48
syn:: Data :: Struct ( struct_data) => parse_fields ( struct_data. fields ) ?,
26
49
_ => {
@@ -31,6 +54,7 @@ impl Parse for PropsMacroInput {
31
54
}
32
55
} ;
33
56
Ok ( Self {
57
+ wrapper_ty : wrapper_ty. wrapper_ty ,
34
58
ident : derive_input. ident ,
35
59
props,
36
60
} )
@@ -454,28 +478,6 @@ fn name_to_ident(name: &syn::LitStr) -> syn::Ident {
454
478
format_ident ! ( "{}" , name. value( ) . replace( '-' , "_" ) )
455
479
}
456
480
457
- fn getter_prototype ( ident : & syn:: Ident , ty : & syn:: Type ) -> TokenStream2 {
458
- let crate_ident = crate_ident_new ( ) ;
459
- quote ! ( fn #ident( & self ) -> <#ty as #crate_ident:: Property >:: Value )
460
- }
461
- fn setter_prototype ( ident : & syn:: Ident , ty : & syn:: Type ) -> TokenStream2 {
462
- let crate_ident = crate_ident_new ( ) ;
463
- let ident = format_ident ! ( "set_{}" , ident) ;
464
- quote ! ( fn #ident( & self , value: & <<#ty as #crate_ident:: Property >:: Value as #crate_ident:: HasParamSpec >:: SetValue ) )
465
- }
466
- fn expand_getset_properties_def ( props : & [ PropDesc ] ) -> TokenStream2 {
467
- let defs = props
468
- . iter ( )
469
- . flat_map ( |p| {
470
- let ident = name_to_ident ( & p. name ) ;
471
- let getter = p. get . is_some ( ) . then ( || getter_prototype ( & ident, & p. ty ) ) ;
472
- let setter = p. set . is_some ( ) . then ( || setter_prototype ( & ident, & p. ty ) ) ;
473
- [ getter, setter]
474
- } )
475
- . flatten ( ) ;
476
- quote ! ( #( #defs; ) * )
477
- }
478
-
479
481
fn expand_getset_properties_impl ( props : & [ PropDesc ] ) -> TokenStream2 {
480
482
let crate_ident = crate_ident_new ( ) ;
481
483
let defs = props. iter ( ) . map ( |p| {
@@ -485,12 +487,16 @@ fn expand_getset_properties_impl(props: &[PropDesc]) -> TokenStream2 {
485
487
486
488
let getter = p. get . is_some ( ) . then ( || {
487
489
let body = quote ! ( self . property:: <<#ty as #crate_ident:: Property >:: Value >( #name) ) ;
488
- let fn_prototype = getter_prototype ( & ident, ty) ;
490
+ let fn_prototype =
491
+ { quote ! ( pub fn #ident( & self ) -> <#ty as #crate_ident:: Property >:: Value ) } ;
489
492
quote ! ( #fn_prototype { #body } )
490
493
} ) ;
491
494
let setter = ( p. set . is_some ( ) && !p. flags . contains ( & "construct_only" ) ) . then ( || {
492
495
let body = quote ! ( self . set_property_from_value( #name, & value. to_value( ) ) ) ;
493
- let fn_prototype = setter_prototype ( & ident, ty) ;
496
+ let fn_prototype = {
497
+ let ident = format_ident ! ( "set_{}" , ident) ;
498
+ quote ! ( pub fn #ident( & self , value: & <<#ty as #crate_ident:: Property >:: Value as #crate_ident:: HasParamSpec >:: SetValue ) )
499
+ } ;
494
500
quote ! ( #fn_prototype { #body } )
495
501
} ) ;
496
502
let span = p. attrs_span ;
@@ -502,20 +508,14 @@ fn expand_getset_properties_impl(props: &[PropDesc]) -> TokenStream2 {
502
508
quote ! ( #( #defs) * )
503
509
}
504
510
505
- fn connect_prop_notify_prototype ( p : & PropDesc ) -> TokenStream2 {
506
- let name = & p. name ;
507
- let crate_ident = crate_ident_new ( ) ;
508
- let fn_ident = format_ident ! ( "connect_{}_notify" , name_to_ident( name) ) ;
509
- quote ! ( fn #fn_ident<F : Fn ( & Self ) + ' static >( & self , f: F ) -> #crate_ident:: SignalHandlerId )
510
- }
511
- fn expand_connect_prop_notify_def ( props : & [ PropDesc ] ) -> TokenStream2 {
512
- let connection_fns = props. iter ( ) . map ( connect_prop_notify_prototype) ;
513
- quote ! ( #( #connection_fns; ) * )
514
- }
515
511
fn expand_connect_prop_notify_impl ( props : & [ PropDesc ] ) -> TokenStream2 {
512
+ let crate_ident = crate_ident_new ( ) ;
516
513
let connection_fns = props. iter ( ) . map ( |p| {
517
514
let name = & p. name ;
518
- let fn_prototype = connect_prop_notify_prototype ( p) ;
515
+ let fn_prototype = {
516
+ let fn_ident = format_ident ! ( "connect_{}_notify" , name_to_ident( name) ) ;
517
+ quote ! ( pub fn #fn_ident<F : Fn ( & Self ) + ' static >( & self , f: F ) -> #crate_ident:: SignalHandlerId )
518
+ } ;
519
519
let span = p. attrs_span ;
520
520
quote_spanned ! ( span=> #fn_prototype {
521
521
self . connect_notify_local( Some ( #name) , move |this, _| {
@@ -526,19 +526,13 @@ fn expand_connect_prop_notify_impl(props: &[PropDesc]) -> TokenStream2 {
526
526
quote ! ( #( #connection_fns) * )
527
527
}
528
528
529
- fn emit_prototype ( p : & PropDesc ) -> TokenStream2 {
530
- let name = & p. name ;
531
- let fn_ident = format_ident ! ( "emit_{}" , name_to_ident( name) ) ;
532
- quote ! ( fn #fn_ident( & self ) )
533
- }
534
- fn expand_emit_def ( props : & [ PropDesc ] ) -> TokenStream2 {
535
- let emit_fns = props. iter ( ) . map ( emit_prototype) ;
536
- quote ! ( #( #emit_fns; ) * )
537
- }
538
529
fn expand_emit_impl ( props : & [ PropDesc ] ) -> TokenStream2 {
539
530
let emit_fns = props. iter ( ) . map ( |p| {
540
531
let name = & p. name ;
541
- let fn_prototype = emit_prototype ( p) ;
532
+ let fn_prototype = {
533
+ let fn_ident = format_ident ! ( "emit_{}" , name_to_ident( name) ) ;
534
+ quote ! ( fn #fn_ident( & self ) )
535
+ } ;
542
536
let span = p. attrs_span ;
543
537
quote_spanned ! ( span=> #fn_prototype {
544
538
self . notify( #name) ;
@@ -549,18 +543,13 @@ fn expand_emit_impl(props: &[PropDesc]) -> TokenStream2 {
549
543
550
544
pub fn impl_derive_props ( input : PropsMacroInput ) -> TokenStream {
551
545
let struct_ident = & input. ident ;
552
- let struct_ident_ext = format_ident ! ( "{}PropertiesExt" , & input. ident) ;
553
546
let crate_ident = crate_ident_new ( ) ;
554
- let wrapper_type =
555
- quote ! ( <#struct_ident as #crate_ident:: subclass:: types:: ObjectSubclass >:: Type ) ;
547
+ let wrapper_type = input. wrapper_ty ;
556
548
let fn_properties = expand_properties_fn ( & input. props ) ;
557
549
let fn_property = expand_property_fn ( & input. props ) ;
558
550
let fn_set_property = expand_set_property_fn ( & input. props ) ;
559
- let getset_properties_def = expand_getset_properties_def ( & input. props ) ;
560
551
let getset_properties_impl = expand_getset_properties_impl ( & input. props ) ;
561
- let connect_prop_notify_def = expand_connect_prop_notify_def ( & input. props ) ;
562
552
let connect_prop_notify_impl = expand_connect_prop_notify_impl ( & input. props ) ;
563
- let emit_def = expand_emit_def ( & input. props ) ;
564
553
let emit_impl = expand_emit_impl ( & input. props ) ;
565
554
let expanded = quote ! {
566
555
use #crate_ident:: { PropertyGet , PropertySet , ToValue } ;
@@ -571,12 +560,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
571
560
#fn_set_property
572
561
}
573
562
574
- pub trait #struct_ident_ext {
575
- #getset_properties_def
576
- #connect_prop_notify_def
577
- #emit_def
578
- }
579
- impl <T : #crate_ident:: IsA <#wrapper_type>> #struct_ident_ext for T {
563
+ impl #wrapper_type {
580
564
#getset_properties_impl
581
565
#connect_prop_notify_impl
582
566
#emit_impl
0 commit comments