From 56c4fcbddce0d27a17a0789413176e1de63ad89b Mon Sep 17 00:00:00 2001 From: Daniel Trnka Date: Mon, 19 Aug 2024 10:33:25 +0200 Subject: [PATCH] Generate embedded_can::Frame trait for each frame --- src/lib.rs | 56 ++++ testing/can-messages/src/messages.rs | 468 +++++++++++++++++++++++++++ 2 files changed, 524 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3e7142a..f3a7efb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,10 @@ pub struct Config<'a> { #[builder(default)] pub impl_error: FeatureConfig<'a>, + /// Optional: Generate `embedded_can::Frame` impl for each frame. Default: `Always` + #[builder(default = FeatureConfig::Always)] + pub impl_embedded_can_frame: FeatureConfig<'a>, + /// Optional: Validate min and max values in generated signal setters. Default: `Always` #[builder(default = FeatureConfig::Always)] pub check_ranges: FeatureConfig<'a>, @@ -428,6 +432,8 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D writeln!(w, "}}")?; writeln!(w)?; + render_embedded_can_frame(&mut w, config, msg)?; + render_debug_impl(&mut w, config, msg)?; render_arbitrary(&mut w, config, msg)?; @@ -1285,6 +1291,56 @@ fn multiplexed_enum_variant_name( )) } +fn render_embedded_can_frame( + w: &mut impl Write, + config: &Config<'_>, + msg: &Message, +) -> Result<(), std::io::Error> { + config.impl_embedded_can_frame.fmt_cfg(w, |w| { + writeln!( + w, + "\ +impl embedded_can::Frame for {0} {{ + fn new(id: impl Into, data: &[u8]) -> Option {{ + if id.into() != Self::MESSAGE_ID {{ + None + }} else {{ + data.try_into().ok() + }} + }} + + fn new_remote(_id: impl Into, _dlc: usize) -> Option {{ + unimplemented!() + }} + + fn is_extended(&self) -> bool {{ + match self.id() {{ + Id::Standard(_) => false, + Id::Extended(_) => true, + }} + }} + + fn is_remote_frame(&self) -> bool {{ + false + }} + + fn id(&self) -> Id {{ + Self::MESSAGE_ID + }} + + fn dlc(&self) -> usize {{ + self.raw.len() + }} + + fn data(&self) -> &[u8] {{ + &self.raw + }} +}}", + type_name(msg.message_name()) + ) + }) +} + fn render_debug_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> Result<()> { match &config.impl_debug { FeatureConfig::Always => {} diff --git a/testing/can-messages/src/messages.rs b/testing/can-messages/src/messages.rs index 8e096ae..6ee9d84 100644 --- a/testing/can-messages/src/messages.rs +++ b/testing/can-messages/src/messages.rs @@ -223,6 +223,42 @@ impl core::convert::TryFrom<&[u8]> for Foo { } } +impl embedded_can::Frame for Foo { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for Foo { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -534,6 +570,42 @@ impl core::convert::TryFrom<&[u8]> for Bar { } } +impl embedded_can::Frame for Bar { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for Bar { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -720,6 +792,42 @@ impl core::convert::TryFrom<&[u8]> for X4wd { } } +impl embedded_can::Frame for X4wd { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for X4wd { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -1028,6 +1136,42 @@ impl core::convert::TryFrom<&[u8]> for Amet { } } +impl embedded_can::Frame for Amet { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for Amet { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -1150,6 +1294,42 @@ impl core::convert::TryFrom<&[u8]> for Dolor { } } +impl embedded_can::Frame for Dolor { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for Dolor { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -1355,6 +1535,42 @@ impl core::convert::TryFrom<&[u8]> for MultiplexTest { } } +impl embedded_can::Frame for MultiplexTest { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for MultiplexTest { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -1866,6 +2082,42 @@ impl core::convert::TryFrom<&[u8]> for IntegerFactorOffset { } } +impl embedded_can::Frame for IntegerFactorOffset { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for IntegerFactorOffset { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2048,6 +2300,42 @@ impl core::convert::TryFrom<&[u8]> for NegativeFactorTest { } } +impl embedded_can::Frame for NegativeFactorTest { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for NegativeFactorTest { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2222,6 +2510,42 @@ impl core::convert::TryFrom<&[u8]> for LargerIntsWithOffsets { } } +impl embedded_can::Frame for LargerIntsWithOffsets { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for LargerIntsWithOffsets { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2286,6 +2610,42 @@ impl core::convert::TryFrom<&[u8]> for MsgWithoutSignals { } } +impl embedded_can::Frame for MsgWithoutSignals { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for MsgWithoutSignals { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2394,6 +2754,42 @@ impl core::convert::TryFrom<&[u8]> for TruncatedBeSignal { } } +impl embedded_can::Frame for TruncatedBeSignal { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for TruncatedBeSignal { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2505,6 +2901,42 @@ impl core::convert::TryFrom<&[u8]> for TruncatedLeSignal { } } +impl embedded_can::Frame for TruncatedLeSignal { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for TruncatedLeSignal { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() { @@ -2614,6 +3046,42 @@ impl core::convert::TryFrom<&[u8]> for MsgExtendedId { } } +impl embedded_can::Frame for MsgExtendedId { + fn new(id: impl Into, data: &[u8]) -> Option { + if id.into() != Self::MESSAGE_ID { + None + } else { + data.try_into().ok() + } + } + + fn new_remote(_id: impl Into, _dlc: usize) -> Option { + unimplemented!() + } + + fn is_extended(&self) -> bool { + match self.id() { + Id::Standard(_) => false, + Id::Extended(_) => true, + } + } + + fn is_remote_frame(&self) -> bool { + false + } + + fn id(&self) -> Id { + Self::MESSAGE_ID + } + + fn dlc(&self) -> usize { + self.raw.len() + } + + fn data(&self) -> &[u8] { + &self.raw + } +} impl core::fmt::Debug for MsgExtendedId { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if f.alternate() {