@@ -510,6 +510,71 @@ fn render_register_mod_debug(
510510 Ok ( r_debug_impl)
511511}
512512
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+
513578#[ allow( clippy:: too_many_arguments) ]
514579pub fn fields (
515580 mut fields : Vec < & Field > ,
@@ -612,14 +677,25 @@ pub fn fields(
612677 lookup_results. push ( ( ev, epath) ) ;
613678 }
614679
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+ } ;
623699
624700 let brief_suffix = if let Field :: Array ( _, de) = & f {
625701 if let Some ( range) = de. indexes_as_range ( ) {
@@ -659,8 +735,8 @@ pub fn fields(
659735
660736 // get the type of value structure. It can be generated from either name field
661737 // 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 ( ) {
664740 "enum_read_name"
665741 } else {
666742 "enum_name"
@@ -680,7 +756,7 @@ pub fn fields(
680756 // information in enumeratedValues;
681757 // if it's not enumeratedValues, always derive the read proxy as we do not need to re-export
682758 // 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 ) ;
684760
685761 // derive the read proxy structure if necessary.
686762 if should_derive_reader {
@@ -715,7 +791,7 @@ pub fn fields(
715791
716792 // if this is an enumeratedValues not derived from base, generate the enum structure
717793 // 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 ( ) {
719795 // parse enum variants from enumeratedValues svd record
720796 let mut variants = Variant :: from_enumerated_values ( evs, config) ?;
721797
@@ -855,7 +931,7 @@ pub fn fields(
855931
856932 // if this value is derived from a base, generate `pub use` code for each read proxy and value
857933 // if necessary.
858- if let Some ( ( _, Some ( base) ) ) = read_enum {
934+ if let Some ( ( _, Some ( base) ) ) = rwenum . read_enum ( ) {
859935 // generate pub use field_1 reader as field_2 reader
860936 let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
861937 let base_r = ident ( & base_field, config, "field_reader" , span) ;
@@ -966,8 +1042,8 @@ pub fn fields(
9661042 // gets a brief of write proxy
9671043 let field_writer_brief = format ! ( "Field `{name}{brief_suffix}` writer - {description}" ) ;
9681044
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 ( ) {
9711047 "enum_write_name"
9721048 } else {
9731049 "enum_name"
@@ -985,7 +1061,7 @@ pub fn fields(
9851061 let mut unsafety = unsafety ( f. write_constraint . as_ref ( ) , width) ;
9861062
9871063 // 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 ( ) {
9891065 // parse variants from enumeratedValues svd record
9901066 let mut variants = Variant :: from_enumerated_values ( evs, config) ?;
9911067 let map = enums_to_map ( evs) ;
@@ -1007,7 +1083,7 @@ pub fn fields(
10071083 }
10081084
10091085 // 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 ( ) {
10111087 if variants. is_empty ( ) {
10121088 add_with_no_variants (
10131089 mod_items,
@@ -1047,7 +1123,7 @@ pub fn fields(
10471123
10481124 // derive writer. We derive writer if the write proxy is in current register module,
10491125 // 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 ) ;
10511127
10521128 // derive writer structure by type alias to generic write proxy structure.
10531129 if should_derive_writer {
@@ -1116,7 +1192,7 @@ pub fn fields(
11161192 } ) ;
11171193 }
11181194
1119- if let Some ( ( _, Some ( base) ) ) = write_enum {
1195+ if let Some ( ( _, Some ( base) ) ) = rwenum . write_enum ( ) {
11201196 // if base.register == None, derive write from the same module. This is allowed because both
11211197 // the generated and source write proxy are in the same module.
11221198 // we never reuse writer for writer in different module does not have the same _SPEC strcuture,
@@ -1135,7 +1211,7 @@ pub fn fields(
11351211 }
11361212 // if base.register == None, it emits pub use structure from same module.
11371213 if base. register ( ) != fpath. register ( ) {
1138- if writer_reader_different_enum {
1214+ if rwenum . gen_write_enum ( ) {
11391215 // use the same enum structure name
11401216 if !writer_enum_derives. contains ( & value_write_ty) {
11411217 let base_path = base_syn_path ( base, & fpath, & value_write_ty, config) ?;
0 commit comments