@@ -510,6 +510,71 @@ fn render_register_mod_debug(
510
510
Ok ( r_debug_impl)
511
511
}
512
512
513
+ type EV = ( EnumeratedValues , Option < EnumPath > ) ;
514
+
515
+ pub enum RWEnum < ' a > {
516
+ ReadAndWriteEnum ( & ' a EV ) ,
517
+ ReadEnumWriteEnum ( & ' a EV , & ' a EV ) ,
518
+ ReadEnumWriteRaw ( & ' a EV ) ,
519
+ ReadRawWriteEnum ( & ' a EV ) ,
520
+ ReadEnum ( & ' a EV ) ,
521
+ ReadRaw ,
522
+ WriteEnum ( & ' a EV ) ,
523
+ WriteRaw ,
524
+ ReadRawWriteRaw ,
525
+ }
526
+ impl < ' a > RWEnum < ' a > {
527
+ pub fn different_enums ( & self ) -> bool {
528
+ matches ! ( self , Self :: ReadEnumWriteEnum ( _, _) )
529
+ }
530
+ pub fn read_write ( & self ) -> bool {
531
+ matches ! (
532
+ self ,
533
+ Self :: ReadAndWriteEnum ( _)
534
+ | Self :: ReadEnumWriteEnum ( _, _)
535
+ | Self :: ReadEnumWriteRaw ( _)
536
+ | Self :: ReadRawWriteEnum ( _)
537
+ | Self :: ReadRawWriteRaw
538
+ )
539
+ }
540
+ pub fn read_only ( & self ) -> bool {
541
+ matches ! ( self , Self :: ReadEnum ( _) | Self :: ReadRaw )
542
+ }
543
+ pub fn can_read ( & self ) -> bool {
544
+ self . read_write ( ) || self . read_only ( )
545
+ }
546
+ pub fn write_only ( & self ) -> bool {
547
+ matches ! ( self , Self :: WriteEnum ( _) | Self :: WriteRaw )
548
+ }
549
+ pub fn can_write ( & self ) -> bool {
550
+ self . read_write ( ) || self . write_only ( )
551
+ }
552
+ pub fn read_enum ( & self ) -> Option < & ' a EV > {
553
+ match * self {
554
+ Self :: ReadAndWriteEnum ( e)
555
+ | Self :: ReadEnumWriteEnum ( e, _)
556
+ | Self :: ReadEnumWriteRaw ( e)
557
+ | Self :: ReadEnum ( e) => Some ( e) ,
558
+ _ => None ,
559
+ }
560
+ }
561
+ pub fn write_enum ( & self ) -> Option < & ' a EV > {
562
+ match * self {
563
+ Self :: ReadAndWriteEnum ( e)
564
+ | Self :: ReadEnumWriteEnum ( _, e)
565
+ | Self :: ReadRawWriteEnum ( e)
566
+ | Self :: WriteEnum ( e) => Some ( e) ,
567
+ _ => None ,
568
+ }
569
+ }
570
+ pub fn gen_write_enum ( & self ) -> bool {
571
+ matches ! (
572
+ self ,
573
+ Self :: ReadEnumWriteEnum ( _, _) | Self :: ReadRawWriteEnum ( _) | Self :: WriteEnum ( _)
574
+ )
575
+ }
576
+ }
577
+
513
578
#[ allow( clippy:: too_many_arguments) ]
514
579
pub fn fields (
515
580
mut fields : Vec < & Field > ,
@@ -612,14 +677,25 @@ pub fn fields(
612
677
lookup_results. push ( ( ev, epath) ) ;
613
678
}
614
679
615
- let read_enum = lookup_filter ( & lookup_results, Usage :: Read ) ;
616
- let write_enum = lookup_filter ( & lookup_results, Usage :: Write ) ;
617
-
618
- // does the read and the write value has the same name? If we have the same,
619
- // we can reuse read value type other than generating a new one.
620
- let writer_reader_different_enum = !( can_read
621
- && can_write
622
- && matches ! ( ( read_enum, write_enum) , ( Some ( e1) , Some ( e2) ) if e1. 0 == e2. 0 ) ) ;
680
+ let rwenum = match (
681
+ can_read,
682
+ lookup_filter ( & lookup_results, Usage :: Read ) ,
683
+ can_write,
684
+ lookup_filter ( & lookup_results, Usage :: Write ) ,
685
+ ) {
686
+ ( true , Some ( e1) , true , Some ( e2) ) if e1. 0 == e2. 0 => RWEnum :: ReadAndWriteEnum ( e1) ,
687
+ ( true , Some ( e1) , true , Some ( e2) ) => RWEnum :: ReadEnumWriteEnum ( e1, e2) ,
688
+ ( true , Some ( e) , true , None ) => RWEnum :: ReadEnumWriteRaw ( e) ,
689
+ ( true , None , true , Some ( e) ) => RWEnum :: ReadRawWriteEnum ( e) ,
690
+ ( true , Some ( e) , false , _) => RWEnum :: ReadEnum ( e) ,
691
+ ( true , None , false , _) => RWEnum :: ReadRaw ,
692
+ ( false , _, true , Some ( e) ) => RWEnum :: WriteEnum ( e) ,
693
+ ( false , _, true , None ) => RWEnum :: WriteRaw ,
694
+ ( true , _, true , _) => RWEnum :: ReadRawWriteRaw ,
695
+ ( false , _, false , _) => {
696
+ return Err ( anyhow ! ( "Field {fpath} is not writtable or readable" ) )
697
+ }
698
+ } ;
623
699
624
700
let brief_suffix = if let Field :: Array ( _, de) = & f {
625
701
if let Some ( range) = de. indexes_as_range ( ) {
@@ -659,8 +735,8 @@ pub fn fields(
659
735
660
736
// get the type of value structure. It can be generated from either name field
661
737
// in enumeratedValues if it's an enumeration, or from field name directly if it's not.
662
- let value_read_ty = if let Some ( ( evs, _) ) = read_enum {
663
- let fmt = if writer_reader_different_enum {
738
+ let value_read_ty = if let Some ( ( evs, _) ) = rwenum . read_enum ( ) {
739
+ let fmt = if rwenum . different_enums ( ) {
664
740
"enum_read_name"
665
741
} else {
666
742
"enum_name"
@@ -680,7 +756,7 @@ pub fn fields(
680
756
// information in enumeratedValues;
681
757
// if it's not enumeratedValues, always derive the read proxy as we do not need to re-export
682
758
// it again from BitReader or FieldReader.
683
- let should_derive_reader = matches ! ( read_enum, Some ( ( _, None ) ) | None ) ;
759
+ let should_derive_reader = matches ! ( rwenum . read_enum( ) , Some ( ( _, None ) ) | None ) ;
684
760
685
761
// derive the read proxy structure if necessary.
686
762
if should_derive_reader {
@@ -715,7 +791,7 @@ pub fn fields(
715
791
716
792
// if this is an enumeratedValues not derived from base, generate the enum structure
717
793
// and implement functions for each value in enumeration.
718
- if let Some ( ( evs, None ) ) = read_enum {
794
+ if let Some ( ( evs, None ) ) = rwenum . read_enum ( ) {
719
795
// parse enum variants from enumeratedValues svd record
720
796
let mut variants = Variant :: from_enumerated_values ( evs, config) ?;
721
797
@@ -855,7 +931,7 @@ pub fn fields(
855
931
856
932
// if this value is derived from a base, generate `pub use` code for each read proxy and value
857
933
// if necessary.
858
- if let Some ( ( _, Some ( base) ) ) = read_enum {
934
+ if let Some ( ( _, Some ( base) ) ) = rwenum . read_enum ( ) {
859
935
// generate pub use field_1 reader as field_2 reader
860
936
let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
861
937
let base_r = ident ( & base_field, config, "field_reader" , span) ;
@@ -966,8 +1042,8 @@ pub fn fields(
966
1042
// gets a brief of write proxy
967
1043
let field_writer_brief = format ! ( "Field `{name}{brief_suffix}` writer - {description}" ) ;
968
1044
969
- let value_write_ty = if let Some ( ( evs, _) ) = write_enum {
970
- let fmt = if writer_reader_different_enum {
1045
+ let value_write_ty = if let Some ( ( evs, _) ) = rwenum . write_enum ( ) {
1046
+ let fmt = if rwenum . different_enums ( ) {
971
1047
"enum_write_name"
972
1048
} else {
973
1049
"enum_name"
@@ -985,7 +1061,7 @@ pub fn fields(
985
1061
let mut unsafety = unsafety ( f. write_constraint . as_ref ( ) , width) ;
986
1062
987
1063
// if we writes to enumeratedValues, generate its structure if it differs from read structure.
988
- if let Some ( ( evs, None ) ) = write_enum {
1064
+ if let Some ( ( evs, None ) ) = rwenum . write_enum ( ) {
989
1065
// parse variants from enumeratedValues svd record
990
1066
let mut variants = Variant :: from_enumerated_values ( evs, config) ?;
991
1067
let map = enums_to_map ( evs) ;
@@ -1007,7 +1083,7 @@ pub fn fields(
1007
1083
}
1008
1084
1009
1085
// generate write value structure and From conversation if we can't reuse read value structure.
1010
- if writer_reader_different_enum {
1086
+ if rwenum . gen_write_enum ( ) {
1011
1087
if variants. is_empty ( ) {
1012
1088
add_with_no_variants (
1013
1089
mod_items,
@@ -1047,7 +1123,7 @@ pub fn fields(
1047
1123
1048
1124
// derive writer. We derive writer if the write proxy is in current register module,
1049
1125
// or writer in different register have different _SPEC structures
1050
- let should_derive_writer = matches ! ( write_enum, Some ( ( _, None ) ) | None ) ;
1126
+ let should_derive_writer = matches ! ( rwenum . write_enum( ) , Some ( ( _, None ) ) | None ) ;
1051
1127
1052
1128
// derive writer structure by type alias to generic write proxy structure.
1053
1129
if should_derive_writer {
@@ -1116,7 +1192,7 @@ pub fn fields(
1116
1192
} ) ;
1117
1193
}
1118
1194
1119
- if let Some ( ( _, Some ( base) ) ) = write_enum {
1195
+ if let Some ( ( _, Some ( base) ) ) = rwenum . write_enum ( ) {
1120
1196
// if base.register == None, derive write from the same module. This is allowed because both
1121
1197
// the generated and source write proxy are in the same module.
1122
1198
// we never reuse writer for writer in different module does not have the same _SPEC strcuture,
@@ -1135,7 +1211,7 @@ pub fn fields(
1135
1211
}
1136
1212
// if base.register == None, it emits pub use structure from same module.
1137
1213
if base. register ( ) != fpath. register ( ) {
1138
- if writer_reader_different_enum {
1214
+ if rwenum . gen_write_enum ( ) {
1139
1215
// use the same enum structure name
1140
1216
if !writer_enum_derives. contains ( & value_write_ty) {
1141
1217
let base_path = base_syn_path ( base, & fpath, & value_write_ty, config) ?;
0 commit comments