From 4c924adb56a85d69e081deca8b56787b0643b344 Mon Sep 17 00:00:00 2001 From: marcelbuesing Date: Mon, 12 Apr 2021 16:33:01 +0200 Subject: [PATCH] Add setters for multiplexed signals --- src/lib.rs | 96 ++++++++++++++++++--- testing/can-messages/src/messages.rs | 124 +++++++++++++-------------- testing/can-messages/tests/all.rs | 23 ++++- testing/dbc-examples/example.dbc | 4 +- 4 files changed, 168 insertions(+), 79 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 63729e3..0a86399 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -204,12 +204,16 @@ fn render_message(mut w: impl Write, msg: &Message, dbc: &DBC) -> Result<()> { let args: Vec = msg .signals() .iter() - .map(|signal| { - format!( - "{}: {}", - field_name(signal.name()), - signal_to_rust_type(&signal) - ) + .filter_map(|signal| { + if *signal.multiplexer_indicator() == MultiplexIndicator::Plain { + Some(format!( + "{}: {}", + field_name(signal.name()), + signal_to_rust_type(&signal) + )) + } else { + None + } }) .collect(); writeln!( @@ -228,10 +232,6 @@ fn render_message(mut w: impl Write, msg: &Message, dbc: &DBC) -> Result<()> { if *signal.multiplexer_indicator() == MultiplexIndicator::Plain { writeln!(&mut w, "res.set_{0}_raw({0})?;", field_name(signal.name()))?; } - - if *signal.multiplexer_indicator() == MultiplexIndicator::Multiplexor { - writeln!(&mut w, "res.set_{0}_raw({0})?;", field_name(signal.name()))?; - } } writeln!(&mut w, "Ok(res)")?; } @@ -406,7 +406,7 @@ fn render_set_signal_raw(mut w: impl Write, signal: &Signal, msg: &Message) -> R writeln!(w, "#[inline(always)]")?; writeln!( w, - "pub fn set_{}_raw(&mut self, value: {}) -> Result<(), CanError> {{", + "pub fn set_{}_raw(&mut self, value: {}) -> Result<&mut Self, CanError> {{", field_name(signal.name()), signal_to_rust_type(&signal) )?; @@ -442,6 +442,54 @@ fn render_set_signal_raw(mut w: impl Write, signal: &Signal, msg: &Message) -> R Ok(()) } +fn render_set_signal_multiplexer( + mut w: impl Write, + multiplexor: &Signal, + msg: &Message, + switch_index: u64, +) -> Result<()> { + writeln!(&mut w, "/// Set value of {}", multiplexor.name())?; + writeln!(w, "#[inline(always)]")?; + writeln!( + w, + "pub fn set_{enum_variant_wrapper}(&mut self) -> Result<{enum_variant}, CanError> {{", + enum_variant_wrapper = multiplexed_enum_variant_wrapper_name(switch_index), + enum_variant = multiplexed_enum_variant_name(msg, multiplexor, switch_index)?, + )?; + + { + // let mut w = PadAdapter::wrap(&mut w); + + // writeln!(&mut w, "match value {{")?; + // { + // let mut w = PadAdapter::wrap(&mut w); + // for (switch_index, multiplexed_signal) in multiplexed_signals { + // writeln!( + // w, + // "{enum_name}::{multiplexed_wrapper_name}(m) => {{self.set_{}(m.MULTIPLEXED_SWITCH_INDEX)?;", + // field_name(multiplexor.name()), + // enum_name = multiplex_enum_name(msg, multiplexor)?, + // multiplexed_wrapper_name = multiplexed_enum_variant_wrapper_name(*switch_index) + // )?; + // } + // } + // writeln!(&mut w, "}}")?; + + let mut w = PadAdapter::wrap(&mut w); + writeln!(&mut w, "self.set_multiplexor_raw({})?;", switch_index)?; + writeln!( + &mut w, + "Ok({} {{ raw: &mut self.raw }})", + enum_variant = multiplexed_enum_variant_name(msg, multiplexor, switch_index)? + )?; + } + + writeln!(&mut w, "}}")?; + writeln!(w)?; + + Ok(()) +} + fn render_multiplexor_signal(mut w: impl Write, signal: &Signal, msg: &Message) -> Result<()> { writeln!(w, "/// Get raw value of {}", signal.name())?; writeln!(w, "///")?; @@ -510,6 +558,22 @@ fn render_multiplexor_signal(mut w: impl Write, signal: &Signal, msg: &Message) render_set_signal_raw(&mut w, signal, msg)?; + // TODO turn this mapping of signals to multiplex_indicator into an extension method for can_dbc::Message or actually add it to can_dbc + let mut multiplexed_signals = BTreeMap::new(); + for signal in msg.signals() { + if let MultiplexIndicator::MultiplexedSignal(switch_index) = signal.multiplexer_indicator() + { + multiplexed_signals + .entry(switch_index) + .and_modify(|v: &mut Vec<&Signal>| v.push(&signal)) + .or_insert(vec![&signal]); + } + } + + for (switch_index, multiplexed_signal) in multiplexed_signals { + render_set_signal_multiplexer(&mut w, signal, msg, *switch_index)?; + } + Ok(()) } @@ -660,7 +724,7 @@ fn signal_to_payload(mut w: impl Write, signal: &Signal, msg: &Message) -> Resul } }; - writeln!(&mut w, "Ok(())")?; + writeln!(&mut w, "Ok(self)")?; Ok(()) } @@ -1023,7 +1087,13 @@ fn render_arbitrary(mut w: impl Write, msg: &Message) -> Result<()> { let args: Vec = msg .signals() .iter() - .map(|signal| field_name(signal.name())) + .filter_map(|signal| { + if *signal.multiplexer_indicator() == MultiplexIndicator::Plain { + Some(field_name(signal.name())) + } else { + None + } + }) .collect(); writeln!( diff --git a/testing/can-messages/src/messages.rs b/testing/can-messages/src/messages.rs index 662c32c..e6f94e3 100644 --- a/testing/can-messages/src/messages.rs +++ b/testing/can-messages/src/messages.rs @@ -112,7 +112,7 @@ impl Foo { /// Set value of Voltage #[inline(always)] - pub fn set_voltage_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_voltage_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 63.9990234375_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 256 }); @@ -122,7 +122,7 @@ impl Foo { let value = ((value - offset) / factor) as u16; self.raw.view_bits_mut::()[16..32].store_le(value); - Ok(()) + Ok(self) } /// Current @@ -156,7 +156,7 @@ impl Foo { /// Set value of Current #[inline(always)] - pub fn set_current_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_current_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < -2048_f32 || 2047.9375_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 256 }); @@ -167,7 +167,7 @@ impl Foo { let value = u16::from_ne_bytes(value.to_ne_bytes()); self.raw.view_bits_mut::()[0..16].store_le(value); - Ok(()) + Ok(self) } } @@ -274,13 +274,13 @@ impl Bar { /// Set value of One #[inline(always)] - pub fn set_one_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_one_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 3_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 512 }); } self.raw.view_bits_mut::()[8..10].store_be(value); - Ok(()) + Ok(self) } /// Two @@ -313,7 +313,7 @@ impl Bar { /// Set value of Two #[inline(always)] - pub fn set_two_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_two_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 100_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 512 }); @@ -323,7 +323,7 @@ impl Bar { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[0..8].store_be(value); - Ok(()) + Ok(self) } /// Three @@ -354,13 +354,13 @@ impl Bar { /// Set value of Three #[inline(always)] - pub fn set_three_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_three_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 7_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 512 }); } self.raw.view_bits_mut::()[10..13].store_be(value); - Ok(()) + Ok(self) } /// Four @@ -391,13 +391,13 @@ impl Bar { /// Set value of Four #[inline(always)] - pub fn set_four_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_four_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 3_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 512 }); } self.raw.view_bits_mut::()[13..15].store_be(value); - Ok(()) + Ok(self) } /// Type @@ -428,10 +428,10 @@ impl Bar { /// Set value of Type #[inline(always)] - pub fn set_xtype_raw(&mut self, value: bool) -> Result<(), CanError> { + pub fn set_xtype_raw(&mut self, value: bool) -> Result<&mut Self, CanError> { let value = value as u8; self.raw.view_bits_mut::()[25..26].store_be(value); - Ok(()) + Ok(self) } } @@ -642,13 +642,13 @@ impl Amet { /// Set value of One #[inline(always)] - pub fn set_one_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_one_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 3_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 1024 }); } self.raw.view_bits_mut::()[8..10].store_be(value); - Ok(()) + Ok(self) } /// Two @@ -681,7 +681,7 @@ impl Amet { /// Set value of Two #[inline(always)] - pub fn set_two_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_two_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 100_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 1024 }); @@ -691,7 +691,7 @@ impl Amet { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[0..8].store_be(value); - Ok(()) + Ok(self) } /// Three @@ -722,13 +722,13 @@ impl Amet { /// Set value of Three #[inline(always)] - pub fn set_three_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_three_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 7_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 1024 }); } self.raw.view_bits_mut::()[19..22].store_be(value); - Ok(()) + Ok(self) } /// Four @@ -759,13 +759,13 @@ impl Amet { /// Set value of Four #[inline(always)] - pub fn set_four_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_four_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_u8 || 3_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 1024 }); } self.raw.view_bits_mut::()[25..27].store_be(value); - Ok(()) + Ok(self) } /// Five @@ -796,10 +796,10 @@ impl Amet { /// Set value of Five #[inline(always)] - pub fn set_five_raw(&mut self, value: bool) -> Result<(), CanError> { + pub fn set_five_raw(&mut self, value: bool) -> Result<&mut Self, CanError> { let value = value as u8; self.raw.view_bits_mut::()[47..48].store_be(value); - Ok(()) + Ok(self) } } @@ -904,7 +904,7 @@ impl Dolor { /// Set value of OneFloat #[inline(always)] - pub fn set_one_float_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_one_float_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 130_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 1028 }); @@ -914,7 +914,7 @@ impl Dolor { let value = ((value - offset) / factor) as u16; self.raw.view_bits_mut::()[7..19].store_be(value); - Ok(()) + Ok(self) } } @@ -995,9 +995,9 @@ impl MultiplexTest { pub const MESSAGE_ID: u32 = 200; pub const MULTIPLEXOR_MIN: u8 = 0_u8; - pub const MULTIPLEXOR_MAX: u8 = 0_u8; + pub const MULTIPLEXOR_MAX: u8 = 2_u8; pub const UNMULTIPLEXED_SIGNAL_MIN: u8 = 0_u8; - pub const UNMULTIPLEXED_SIGNAL_MAX: u8 = 0_u8; + pub const UNMULTIPLEXED_SIGNAL_MAX: u8 = 4_u8; pub const MULTIPLEXED_SIGNAL_ZERO_A_MIN: f32 = 0_f32; pub const MULTIPLEXED_SIGNAL_ZERO_A_MAX: f32 = 3_f32; pub const MULTIPLEXED_SIGNAL_ZERO_B_MIN: f32 = 0_f32; @@ -1008,16 +1008,8 @@ impl MultiplexTest { pub const MULTIPLEXED_SIGNAL_ONE_B_MAX: f32 = 6_f32; /// Construct new MultiplexTest from values - pub fn new( - multiplexor: u8, - unmultiplexed_signal: u8, - multiplexed_signal_zero_a: f32, - multiplexed_signal_zero_b: f32, - multiplexed_signal_one_a: f32, - multiplexed_signal_one_b: f32, - ) -> Result { + pub fn new(unmultiplexed_signal: u8) -> Result { let mut res = Self { raw: [0u8; 8] }; - res.set_multiplexor_raw(multiplexor)?; res.set_unmultiplexed_signal_raw(unmultiplexed_signal)?; Ok(res) } @@ -1051,19 +1043,33 @@ impl MultiplexTest { } /// Set value of Multiplexor #[inline(always)] - pub fn set_multiplexor_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_multiplexor_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] - if value < 0_u8 || 0_u8 < value { + if value < 0_u8 || 2_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); } self.raw.view_bits_mut::()[0..4].store_le(value); - Ok(()) + Ok(self) + } + + /// Set value of Multiplexor + #[inline(always)] + pub fn set_M0(&mut self) -> Result { + self.set_multiplexor_raw(0)?; + Ok(MultiplexTestMultiplexorM0 { raw: &mut self.raw }) + } + + /// Set value of Multiplexor + #[inline(always)] + pub fn set_M1(&mut self) -> Result { + self.set_multiplexor_raw(1)?; + Ok(MultiplexTestMultiplexorM1 { raw: &mut self.raw }) } /// UnmultiplexedSignal /// /// - Min: 0 - /// - Max: 0 + /// - Max: 4 /// - Unit: "" /// - Receivers: Vector__XXX #[inline(always)] @@ -1088,13 +1094,13 @@ impl MultiplexTest { /// Set value of UnmultiplexedSignal #[inline(always)] - pub fn set_unmultiplexed_signal_raw(&mut self, value: u8) -> Result<(), CanError> { + pub fn set_unmultiplexed_signal_raw(&mut self, value: u8) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] - if value < 0_u8 || 0_u8 < value { + if value < 0_u8 || 4_u8 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); } self.raw.view_bits_mut::()[4..12].store_le(value); - Ok(()) + Ok(self) } } @@ -1128,21 +1134,13 @@ impl core::fmt::Debug for MultiplexTest { #[cfg(feature = "arb")] impl<'a> Arbitrary<'a> for MultiplexTest { fn arbitrary(u: &mut Unstructured<'a>) -> Result { - let multiplexor = u.int_in_range(0..=0)?; - let unmultiplexed_signal = u.int_in_range(0..=0)?; + let multiplexor = u.int_in_range(0..=2)?; + let unmultiplexed_signal = u.int_in_range(0..=4)?; let multiplexed_signal_zero_a = u.float_in_range(0_f32..=3_f32)?; let multiplexed_signal_zero_b = u.float_in_range(0_f32..=3_f32)?; let multiplexed_signal_one_a = u.float_in_range(0_f32..=6_f32)?; let multiplexed_signal_one_b = u.float_in_range(0_f32..=6_f32)?; - MultiplexTest::new( - multiplexor, - unmultiplexed_signal, - multiplexed_signal_zero_a, - multiplexed_signal_zero_b, - multiplexed_signal_one_a, - multiplexed_signal_one_b, - ) - .map_err(|_| arbitrary::Error::IncorrectFormat) + MultiplexTest::new(unmultiplexed_signal).map_err(|_| arbitrary::Error::IncorrectFormat) } } /// Defined values for multiplexed signal MultiplexTest @@ -1190,7 +1188,7 @@ impl<'a> MultiplexTestMultiplexorM0<'a> { /// Set value of MultiplexedSignalZeroA #[inline(always)] - pub fn set_multiplexed_signal_zero_a_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_multiplexed_signal_zero_a_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 3_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); @@ -1200,7 +1198,7 @@ impl<'a> MultiplexTestMultiplexorM0<'a> { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[12..20].store_le(value); - Ok(()) + Ok(self) } /// MultiplexedSignalZeroB @@ -1233,7 +1231,7 @@ impl<'a> MultiplexTestMultiplexorM0<'a> { /// Set value of MultiplexedSignalZeroB #[inline(always)] - pub fn set_multiplexed_signal_zero_b_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_multiplexed_signal_zero_b_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 3_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); @@ -1243,7 +1241,7 @@ impl<'a> MultiplexTestMultiplexorM0<'a> { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[20..28].store_le(value); - Ok(()) + Ok(self) } } @@ -1285,7 +1283,7 @@ impl<'a> MultiplexTestMultiplexorM1<'a> { /// Set value of MultiplexedSignalOneA #[inline(always)] - pub fn set_multiplexed_signal_one_a_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_multiplexed_signal_one_a_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 6_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); @@ -1295,7 +1293,7 @@ impl<'a> MultiplexTestMultiplexorM1<'a> { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[12..20].store_le(value); - Ok(()) + Ok(self) } /// MultiplexedSignalOneB @@ -1328,7 +1326,7 @@ impl<'a> MultiplexTestMultiplexorM1<'a> { /// Set value of MultiplexedSignalOneB #[inline(always)] - pub fn set_multiplexed_signal_one_b_raw(&mut self, value: f32) -> Result<(), CanError> { + pub fn set_multiplexed_signal_one_b_raw(&mut self, value: f32) -> Result<&mut Self, CanError> { #[cfg(feature = "range_checked")] if value < 0_f32 || 6_f32 < value { return Err(CanError::ParameterOutOfRange { message_id: 200 }); @@ -1338,7 +1336,7 @@ impl<'a> MultiplexTestMultiplexorM1<'a> { let value = ((value - offset) / factor) as u8; self.raw.view_bits_mut::()[20..28].store_le(value); - Ok(()) + Ok(self) } } diff --git a/testing/can-messages/tests/all.rs b/testing/can-messages/tests/all.rs index 112f5fd..6521bde 100644 --- a/testing/can-messages/tests/all.rs +++ b/testing/can-messages/tests/all.rs @@ -1,6 +1,6 @@ #![allow(clippy::float_cmp)] -use can_messages::{Amet, Bar, BarThree, CanError, Foo}; +use can_messages::{Amet, Bar, BarThree, CanError, Foo, MultiplexTest, MultiplexTestMultiplexor}; #[test] #[cfg(feature = "range_checked")] @@ -55,6 +55,27 @@ fn pack_unpack_message2() { assert_eq!(result.five_raw(), true); } +#[test] +fn pack_unpack_message_containing_multiplexed_signals() { + let mut result = MultiplexTest::new(2).unwrap(); + result + .set_M0() + .unwrap() + .set_multiplexed_signal_zero_a_raw(1.2) + .unwrap() + .set_multiplexed_signal_zero_b_raw(2.0) + .unwrap(); + assert_eq!(result.unmultiplexed_signal(), 2); + assert_eq!(result.multiplexor_raw(), 0); + let multiplexor = result.multiplexor(); + if let MultiplexTestMultiplexor::M0(m0) = multiplexor { + assert_eq!(m0.multiplexed_signal_zero_a(), 1.2); + assert_eq!(m0.multiplexed_signal_zero_b(), 2.0); + } else { + panic!("Invalid multiplexor value"); + } +} + #[test] #[cfg(feature = "debug")] fn debug_impl() { diff --git a/testing/dbc-examples/example.dbc b/testing/dbc-examples/example.dbc index 1f11f3d..f1ce493 100644 --- a/testing/dbc-examples/example.dbc +++ b/testing/dbc-examples/example.dbc @@ -30,8 +30,8 @@ BO_ 1028 Dolor: 8 Sit SG_ OneFloat : 0|12@0+ (0.5,0) [0.00|130.00] "" Vector__XXX BO_ 200 MultiplexTest: 8 SENSOR - SG_ Multiplexor M : 0|4@1+ (1,0) [0|0] "" Vector__XXX - SG_ UnmultiplexedSignal : 4|8@1+ (1,0) [0|0] "" Vector__XXX + SG_ Multiplexor M : 0|4@1+ (1,0) [0|2] "" Vector__XXX + SG_ UnmultiplexedSignal : 4|8@1+ (1,0) [0|4] "" Vector__XXX SG_ MultiplexedSignalZeroA m0 : 12|8@1+ (0.1,0) [0|3] "" Vector__XXX SG_ MultiplexedSignalZeroB m0 : 20|8@1+ (0.1,0) [0|3] "" Vector__XXX SG_ MultiplexedSignalOneA m1 : 12|8@1+ (0.1,0) [0|6] "" Vector__XXX