@@ -372,14 +372,14 @@ impl Config<'_> {
372372
373373 self . render_attribute_structs ( & mut w, msg, dbc) ?;
374374
375- writeln ! ( w, "/// Construct new {} from values" , msg. name) ?;
375+ writeln ! ( w, "/// Construct new '{}' from values" , msg. name) ?;
376376 let args = msg
377377 . signals
378378 . iter ( )
379379 . filter_map ( |signal| {
380380 if matches ! ( signal. multiplexer_indicator, Plain | Multiplexor ) {
381381 let field = signal. field_name ( ) ;
382- let typ = ValType :: from_signal ( signal) ;
382+ let typ = signal_pub_type ( dbc , msg , signal) ;
383383 Some ( format ! ( "{field}: {typ}" ) )
384384 } else {
385385 None
@@ -426,7 +426,7 @@ impl Config<'_> {
426426 . render_signal ( & mut w, signal, dbc, msg)
427427 . with_context ( || format ! ( "write signal impl `{}`" , signal. name) ) ?,
428428 Multiplexor => {
429- self . render_multiplexor_signal ( & mut w, signal, msg) ?;
429+ self . render_multiplexor_signal ( & mut w, signal, dbc , msg) ?;
430430 }
431431 MultiplexedSignal ( _) | MultiplexorAndMultiplexedSignal ( _) => { }
432432 }
@@ -470,7 +470,7 @@ impl Config<'_> {
470470 self . impl_defmt
471471 . fmt_cfg ( & mut * w, |w| render_defmt_impl ( w, msg) ) ?;
472472 self . impl_arbitrary
473- . fmt_cfg ( & mut * w, |w| self . render_arbitrary ( w, msg) ) ?;
473+ . fmt_cfg ( & mut * w, |w| self . render_arbitrary ( w, dbc , msg) ) ?;
474474
475475 let enums_for_this_message = dbc. value_descriptions . iter ( ) . filter_map ( |x| {
476476 if let ValueDescription :: Signal {
@@ -685,7 +685,7 @@ impl Config<'_> {
685685 dbc : & Dbc ,
686686 msg : & Message ,
687687 ) -> Result < ( ) > {
688- writeln ! ( w, "/// {} " , signal. name) ?;
688+ writeln ! ( w, "/// Get value of '{}' " , signal. name) ?;
689689 if let Some ( comment) = dbc. signal_comment ( msg. id , & signal. name ) {
690690 writeln ! ( w, "///" ) ?;
691691 for line in comment. trim ( ) . lines ( ) {
@@ -756,7 +756,7 @@ impl Config<'_> {
756756 writeln ! ( w) ?;
757757 }
758758
759- writeln ! ( w, "/// Get raw value of {} " , signal. name) ?;
759+ writeln ! ( w, "/// Get raw value of '{}' " , signal. name) ?;
760760 writeln ! ( w, "///" ) ?;
761761 writeln ! ( w, "/// - Start bit: {}" , signal. start_bit) ?;
762762 writeln ! ( w, "/// - Signal size: {} bits" , signal. size) ?;
@@ -774,15 +774,18 @@ impl Config<'_> {
774774 writeln ! ( w, "}}" ) ?;
775775 writeln ! ( w) ?;
776776
777- self . render_set_signal ( w, signal, msg) ?;
777+ self . render_set_signal ( w, signal, dbc , msg) ?;
778778
779779 Ok ( ( ) )
780780 }
781781
782- fn render_set_signal ( & self , w : & mut impl Write , signal : & Signal , msg : & Message ) -> Result < ( ) > {
783- writeln ! ( w, "/// Set value of {}" , signal. name) ?;
784- writeln ! ( w, "#[inline(always)]" ) ?;
785-
782+ fn render_set_signal (
783+ & self ,
784+ w : & mut impl Write ,
785+ signal : & Signal ,
786+ dbc : & Dbc ,
787+ msg : & Message ,
788+ ) -> Result < ( ) > {
786789 // To avoid accidentally changing the multiplexor value without changing
787790 // the signals accordingly this fn is kept private for multiplexors.
788791 let visibility = if signal. multiplexer_indicator == Multiplexor {
@@ -793,42 +796,60 @@ impl Config<'_> {
793796
794797 let field = signal. field_name ( ) ;
795798 let typ = ValType :: from_signal ( signal) ;
799+ let param_type = signal_pub_type ( dbc, msg, signal) ;
800+ let is_enum_backed = param_type != typ. to_string ( ) ;
801+
802+ writeln ! ( w, "/// Set value of '{}'" , signal. name) ?;
803+ writeln ! ( w, "#[inline(always)]" ) ?;
796804 writeln ! (
797805 w,
798- "{visibility}fn set_{field}(&mut self, value: {typ }) -> Result<(), CanError> {{" ,
806+ "{visibility}fn set_{field}(&mut self, value: {param_type }) -> Result<(), CanError> {{" ,
799807 ) ?;
800-
801808 {
802809 let mut w = PadAdapter :: wrap ( w) ;
810+ // Enum-backed signals accept the value-description enum; convert it to
811+ // the raw primitive before range checks and packing.
812+ if is_enum_backed {
813+ writeln ! ( w, "let value = {typ}::from(value);" ) ?;
814+ }
815+ self . render_set_signal_body ( & mut w, signal, msg) ?;
816+ }
817+ writeln ! ( w, "}}" ) ?;
818+ writeln ! ( w) ?;
803819
804- if signal. size != 1 {
805- if let FeatureConfig :: Gated ( gate) = self . check_ranges {
806- writeln ! ( w, r"#[cfg(feature = {gate:?})]" ) ?;
807- }
820+ Ok ( ( ) )
821+ }
808822
809- if let FeatureConfig :: Gated ( ..) | FeatureConfig :: Always = self . check_ranges {
810- let typ = ValType :: from_signal ( signal) ;
811- let min = signal. min ;
812- let max = signal. max ;
813- writeln ! ( w, r"if value < {min}_{typ} || {max}_{typ} < value {{" ) ?;
823+ fn render_set_signal_body (
824+ & self ,
825+ w : & mut impl Write ,
826+ signal : & Signal ,
827+ msg : & Message ,
828+ ) -> Result < ( ) > {
829+ if signal. size != 1 {
830+ if let FeatureConfig :: Gated ( gate) = self . check_ranges {
831+ writeln ! ( w, r"#[cfg(feature = {gate:?})]" ) ?;
832+ }
814833
815- {
816- let mut w = PadAdapter :: wrap ( & mut w) ;
817- let typ = msg. type_name ( ) ;
818- writeln ! (
819- w,
820- r"return Err(CanError::ParameterOutOfRange {{ message_id: {typ}::MESSAGE_ID }});" ,
821- ) ?;
822- }
834+ if let FeatureConfig :: Gated ( ..) | FeatureConfig :: Always = self . check_ranges {
835+ let typ = ValType :: from_signal ( signal) ;
836+ let min = signal. min ;
837+ let max = signal. max ;
838+ writeln ! ( w, r"if value < {min}_{typ} || {max}_{typ} < value {{" ) ?;
823839
824- writeln ! ( w, r"}}" ) ?;
840+ {
841+ let mut w = PadAdapter :: wrap ( & mut * w) ;
842+ let typ = msg. type_name ( ) ;
843+ writeln ! (
844+ w,
845+ r"return Err(CanError::ParameterOutOfRange {{ message_id: {typ}::MESSAGE_ID }});" ,
846+ ) ?;
825847 }
848+
849+ writeln ! ( w, r"}}" ) ?;
826850 }
827- signal_to_payload ( & mut w, signal, msg) . context ( "signal to payload" ) ?;
828851 }
829-
830- writeln ! ( w, "}}" ) ?;
831- writeln ! ( w) ?;
852+ signal_to_payload ( & mut * w, signal, msg) . context ( "signal to payload" ) ?;
832853
833854 Ok ( ( ) )
834855 }
@@ -837,9 +858,10 @@ impl Config<'_> {
837858 & self ,
838859 w : & mut impl Write ,
839860 signal : & Signal ,
861+ dbc : & Dbc ,
840862 msg : & Message ,
841863 ) -> Result < ( ) > {
842- writeln ! ( w, "/// Get raw value of {} " , signal. name) ?;
864+ writeln ! ( w, "/// Get raw value of '{}' " , signal. name) ?;
843865 writeln ! ( w, "///" ) ?;
844866 writeln ! ( w, "/// - Start bit: {}" , signal. start_bit) ?;
845867 writeln ! ( w, "/// - Signal size: {} bits" , signal. size) ?;
@@ -906,7 +928,7 @@ impl Config<'_> {
906928 }
907929 writeln ! ( w, "}}" ) ?;
908930
909- self . render_set_signal ( w, signal, msg) ?;
931+ self . render_set_signal ( w, signal, dbc , msg) ?;
910932
911933 for switch_index in multiplexer_indexes {
912934 render_set_signal_multiplexer ( w, signal, msg, switch_index) ?;
@@ -999,7 +1021,7 @@ fn render_set_signal_multiplexer(
9991021 msg : & Message ,
10001022 switch_index : u64 ,
10011023) -> Result < ( ) > {
1002- writeln ! ( w, "/// Set value of {} " , multiplexor. name) ?;
1024+ writeln ! ( w, "/// Set value of '{}' " , multiplexor. name) ?;
10031025 writeln ! ( w, "#[inline(always)]" ) ?;
10041026 writeln ! (
10051027 w,
@@ -1070,6 +1092,21 @@ fn le_start_end_bit(signal: &Signal, msg: &Message) -> Result<(u64, u64)> {
10701092 Ok ( ( start_bit, end_bit) )
10711093}
10721094
1095+ /// Public type of a signal as seen by `new()` and `set_*`. This is the
1096+ /// enum when the signal has one (and isn't the multiplexor selector), otherwise
1097+ /// it is the raw primitive type.
1098+ fn signal_pub_type ( dbc : & Dbc , msg : & Message , signal : & Signal ) -> String {
1099+ if signal. multiplexer_indicator != Multiplexor
1100+ && dbc
1101+ . value_descriptions_for_signal ( msg. id , & signal. name )
1102+ . is_some ( )
1103+ {
1104+ enum_name ( msg, signal)
1105+ } else {
1106+ ValType :: from_signal ( signal) . to_string ( )
1107+ }
1108+ }
1109+
10731110fn signal_from_payload ( w : & mut impl Write , signal : & Signal , msg : & Message ) -> Result < ( ) > {
10741111 writeln ! ( w, r"let signal = {};" , read_fn( signal, msg) ?) ?;
10751112 writeln ! ( w) ?;
@@ -1450,7 +1487,7 @@ impl Config<'_> {
14501487 Ok ( ( ) )
14511488 }
14521489
1453- fn render_arbitrary ( & self , w : & mut impl Write , msg : & Message ) -> Result < ( ) > {
1490+ fn render_arbitrary ( & self , w : & mut impl Write , dbc : & Dbc , msg : & Message ) -> Result < ( ) > {
14541491 writeln ! ( w, "{ALLOW_LINTS}" ) ?;
14551492 self . write_allow_dead_code ( w) ?;
14561493 let typ = msg. type_name ( ) ;
@@ -1481,7 +1518,16 @@ impl Config<'_> {
14811518
14821519 let args: Vec < String > = filtered_signals
14831520 . iter ( )
1484- . map ( |signal| signal. field_name ( ) )
1521+ . map ( |signal| {
1522+ let field = signal. field_name ( ) ;
1523+ let is_enum_backed = signal_pub_type ( dbc, msg, signal)
1524+ != ValType :: from_signal ( signal) . to_string ( ) ;
1525+ if is_enum_backed {
1526+ format ! ( "{}::_Other({field})" , enum_name( msg, signal) )
1527+ } else {
1528+ field
1529+ }
1530+ } )
14851531 . collect ( ) ;
14861532
14871533 writeln ! (
0 commit comments