@@ -364,19 +364,20 @@ fn expand_property_fn(props: &[PropDesc]) -> TokenStream2 {
364
364
..
365
365
} = p;
366
366
367
+ let enum_ident = name_to_enum_ident ( name. value ( ) ) ;
367
368
let span = p. attrs_span ;
368
369
get. as_ref ( ) . map ( |get| {
369
370
let body = match ( member, get) {
370
371
( _, MaybeCustomFn :: Custom ( expr) ) => quote ! (
371
- #name => Ok ( ( #expr) ( & self ) . to_value( ) )
372
+ DerivedPropertiesEnum :: #enum_ident => Ok ( ( #expr) ( & self ) . to_value( ) )
372
373
) ,
373
374
( None , MaybeCustomFn :: Default ) => quote ! (
374
- #name => Ok (
375
+ DerivedPropertiesEnum :: #enum_ident => Ok (
375
376
#crate_ident:: PropertyGet :: get( & self . #field_ident, |v| v. to_value( ) )
376
377
)
377
378
) ,
378
379
( Some ( member) , MaybeCustomFn :: Default ) => quote ! (
379
- #name => Ok (
380
+ DerivedPropertiesEnum :: #enum_ident => Ok (
380
381
#crate_ident:: PropertyGet :: get( & self . #field_ident, |v| v. #member. to_value( ) )
381
382
)
382
383
) ,
@@ -385,10 +386,12 @@ fn expand_property_fn(props: &[PropDesc]) -> TokenStream2 {
385
386
} )
386
387
} ) ;
387
388
quote ! (
388
- fn derived_property<' a>( & self , _obj: & Self :: Type , _id: usize , pspec: & ' a #crate_ident:: ParamSpec ) -> Result <#crate_ident:: Value , #crate_ident:: subclass:: object:: MissingPropertyHandler <' a>> {
389
- match pspec. name( ) {
389
+ fn derived_property<' a>( & self , _obj: & Self :: Type , id: usize , pspec: & ' a #crate_ident:: ParamSpec ) -> Result <#crate_ident:: Value , #crate_ident:: subclass:: object:: MissingPropertyHandler <' a>> {
390
+ let prop = DerivedPropertiesEnum :: try_from( id-1 )
391
+ . map_err( |_| #crate_ident:: subclass:: object:: MissingPropertyHandler :: <' a>:: from( pspec) ) ?;
392
+ match prop {
390
393
#( #match_branch_get, ) *
391
- p => Err ( pspec. into( ) )
394
+ _ => Err ( pspec. into( ) )
392
395
}
393
396
}
394
397
)
@@ -405,18 +408,19 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
405
408
} = p;
406
409
407
410
let crate_ident = crate_ident_new ( ) ;
411
+ let enum_ident = name_to_enum_ident ( name. value ( ) ) ;
408
412
let span = p. attrs_span ;
409
413
let expect = quote ! ( . expect( "Can't convert glib::value to property type" ) ) ;
410
414
set. as_ref ( ) . map ( |set| {
411
415
let body = match ( member, set) {
412
416
( _, MaybeCustomFn :: Custom ( expr) ) => quote ! (
413
- #name => {
417
+ DerivedPropertiesEnum :: #enum_ident => {
414
418
( #expr) ( & self , #crate_ident:: Value :: get( value) #expect) ;
415
419
Ok ( ( ) )
416
420
}
417
421
) ,
418
422
( None , MaybeCustomFn :: Default ) => quote ! (
419
- #name => {
423
+ DerivedPropertiesEnum :: #enum_ident => {
420
424
#crate_ident:: PropertySet :: set(
421
425
& self . #field_ident,
422
426
#crate_ident:: Value :: get( value) #expect
@@ -425,7 +429,7 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
425
429
}
426
430
) ,
427
431
( Some ( member) , MaybeCustomFn :: Default ) => quote ! (
428
- #name => {
432
+ DerivedPropertiesEnum :: #enum_ident => {
429
433
#crate_ident:: PropertySetNested :: set_nested(
430
434
& self . #field_ident,
431
435
move |v| v. #member = #crate_ident:: Value :: get( value) #expect
@@ -438,10 +442,12 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
438
442
} )
439
443
} ) ;
440
444
quote ! (
441
- fn derived_set_property<' a>( & self , _obj: & Self :: Type , _id: usize , value: & #crate_ident:: Value , pspec: & ' a #crate_ident:: ParamSpec ) -> Result <( ) , #crate_ident:: subclass:: object:: MissingPropertyHandler <' a>> {
442
- match pspec. name( ) {
445
+ fn derived_set_property<' a>( & self , _obj: & Self :: Type , id: usize , value: & #crate_ident:: Value , pspec: & ' a #crate_ident:: ParamSpec ) -> Result <( ) , #crate_ident:: subclass:: object:: MissingPropertyHandler <' a>> {
446
+ let prop = DerivedPropertiesEnum :: try_from( id-1 )
447
+ . map_err( |_| #crate_ident:: subclass:: object:: MissingPropertyHandler :: <' a>:: from( pspec) ) ?;
448
+ match prop {
443
449
#( #match_branch_set, ) *
444
- p => Err ( pspec. into( ) )
450
+ _ => Err ( pspec. into( ) )
445
451
}
446
452
}
447
453
)
@@ -527,20 +533,71 @@ fn expand_connect_prop_notify_impl(props: &[PropDesc]) -> TokenStream2 {
527
533
}
528
534
529
535
fn expand_emit_impl ( props : & [ PropDesc ] ) -> TokenStream2 {
536
+ let crate_ident = crate_ident_new ( ) ;
530
537
let emit_fns = props. iter ( ) . map ( |p| {
531
538
let name = & p. name ;
532
539
let fn_prototype = {
533
540
let fn_ident = format_ident ! ( "emit_{}" , name_to_ident( name) ) ;
534
541
quote ! ( pub fn #fn_ident( & self ) )
535
542
} ;
536
543
let span = p. attrs_span ;
544
+ let enum_ident = name_to_enum_ident ( name. value ( ) ) ;
537
545
quote_spanned ! ( span=> #fn_prototype {
538
- self . notify( #name) ;
546
+ self . notify_by_pspec(
547
+ & <<Self as #crate_ident:: object:: ObjectSubclassIs >:: Subclass
548
+ as #crate_ident:: subclass:: object:: DerivedObjectProperties >:: derived_properties( )
549
+ [ DerivedPropertiesEnum :: #enum_ident as usize ]
550
+ ) ;
539
551
} )
540
552
} ) ;
541
553
quote ! ( #( #emit_fns) * )
542
554
}
543
555
556
+ fn name_to_enum_ident ( mut name : String ) -> syn:: Ident {
557
+ let mut slice = name. as_mut_str ( ) ;
558
+ while let Some ( i) = slice. find ( '-' ) {
559
+ let ( head, tail) = slice. split_at_mut ( i) ;
560
+ if let Some ( c) = head. get_mut ( 0 ..1 ) {
561
+ c. make_ascii_uppercase ( ) ;
562
+ }
563
+ slice = & mut tail[ 1 ..] ;
564
+ }
565
+ if let Some ( c) = slice. get_mut ( 0 ..1 ) {
566
+ c. make_ascii_uppercase ( ) ;
567
+ }
568
+ let enum_member: String = name. split ( '-' ) . collect ( ) ;
569
+ format_ident ! ( "{}" , enum_member)
570
+ }
571
+
572
+ fn expand_properties_enum ( props : & [ PropDesc ] ) -> TokenStream2 {
573
+ let properties: Vec < syn:: Ident > = props
574
+ . iter ( )
575
+ . map ( |p| {
576
+ let name: String = p. name . value ( ) ;
577
+ name_to_enum_ident ( name)
578
+ } )
579
+ . collect ( ) ;
580
+ let props = properties. iter ( ) ;
581
+ let indices = 0 ..properties. len ( ) ;
582
+ quote ! {
583
+ #[ repr( usize ) ]
584
+ #[ derive( Debug , Copy , Clone ) ]
585
+ enum DerivedPropertiesEnum {
586
+ #( #props, ) *
587
+ }
588
+ impl std:: convert:: TryFrom <usize > for DerivedPropertiesEnum {
589
+ type Error = usize ;
590
+
591
+ fn try_from( item: usize ) -> Result <Self , Self :: Error > {
592
+ match item {
593
+ #( #indices => Ok ( Self :: #properties) , ) *
594
+ _ => Err ( item)
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+
544
601
pub fn impl_derive_props ( input : PropsMacroInput ) -> TokenStream {
545
602
let struct_ident = & input. ident ;
546
603
let crate_ident = crate_ident_new ( ) ;
@@ -551,9 +608,13 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
551
608
let getset_properties_impl = expand_getset_properties_impl ( & input. props ) ;
552
609
let connect_prop_notify_impl = expand_connect_prop_notify_impl ( & input. props ) ;
553
610
let emit_impl = expand_emit_impl ( & input. props ) ;
611
+ let properties_enum = expand_properties_enum ( & input. props ) ;
612
+
554
613
let expanded = quote ! {
555
614
use #crate_ident:: { PropertyGet , PropertySet , ToValue } ;
556
615
616
+ #properties_enum
617
+
557
618
impl #crate_ident:: subclass:: object:: DerivedObjectProperties for #struct_ident {
558
619
#fn_properties
559
620
#fn_property
0 commit comments