diff --git a/Cargo.lock b/Cargo.lock index a87ae59..eb39ddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,7 +93,7 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags", + "bitflags 2.5.0", "cexpr", "clang-sys", "itertools", @@ -110,6 +110,12 @@ dependencies = [ "which", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.5.0" @@ -144,6 +150,7 @@ version = "0.1.0" dependencies = [ "bitvec", "can-messages", + "defmt", "embedded-can", ] @@ -155,6 +162,7 @@ dependencies = [ "arbitrary", "bitvec", "dbc-codegen", + "defmt", "embedded-can", ] @@ -266,6 +274,38 @@ dependencies = [ "heck 0.4.1", ] +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.61", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + [[package]] name = "derive-getters" version = "0.3.0" @@ -449,6 +489,30 @@ dependencies = [ "syn 2.0.61", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.82" @@ -523,7 +587,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -570,6 +634,26 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "typed-builder" version = "0.18.2" @@ -602,6 +686,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "which" version = "4.4.2" diff --git a/src/lib.rs b/src/lib.rs index c6fbee1..7f7d2df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,10 @@ pub struct Config<'a> { #[builder(default)] pub impl_serde: FeatureConfig<'a>, + /// Optional: `impl defmt::Format` for generated types.. Default: `Never`. + #[builder(default)] + pub impl_defmt: FeatureConfig<'a>, + /// Optional: `impl Error` for generated error type. Default: `Never`. /// /// Note: this feature depends on `std`. @@ -85,6 +89,10 @@ pub struct Config<'a> { /// Optional: Allow dead code in the generated module. Default: `false`. #[builder(default)] pub allow_dead_code: bool, + + /// Optional: Padding value used; set all unused bits to 1 if true else 0. Default: `false`. + #[builder(default)] + pub padding_value: bool, } /// Configuration for including features in the codegenerator. @@ -153,6 +161,10 @@ pub fn codegen(config: Config<'_>, out: impl Write) -> Result<()> { writeln!(w, "use arbitrary::{{Arbitrary, Unstructured}};") })?; + config.impl_defmt.fmt_cfg(&mut w, |w| { + writeln!(w, "use defmt::Format;") + })?; + config.impl_serde.fmt_cfg(&mut w, |w| { writeln!(w, "use serde::{{Serialize, Deserialize}};") })?; @@ -258,6 +270,7 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D writeln!(w, "#[derive(Clone, Copy)]")?; config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?; config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?; + config.impl_serde.fmt_attr(&mut w, "derive(defmt::Format)")?; writeln!(w, "pub struct {} {{", type_name(msg.message_name()))?; { let mut w = PadAdapter::wrap(&mut w); @@ -345,8 +358,9 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D let mut w = PadAdapter::wrap(&mut w); writeln!( &mut w, - "let {}res = Self {{ raw: [0u8; {}] }};", + "let {}res = Self {{ raw: [{}; {}] }};", if msg.signals().is_empty() { "" } else { "mut " }, + if config.padding_value { "0xFF" } else { "0x00" }, msg.message_size() )?; for signal in msg.signals().iter() { @@ -986,6 +1000,7 @@ fn write_enum( config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?; config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?; config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?; + config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?; writeln!(w, "pub enum {} {{", type_name)?; { let mut w = PadAdapter::wrap(&mut w); @@ -1418,6 +1433,7 @@ fn render_multiplexor_enums( config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?; config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?; config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?; + config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?; writeln!( w, "pub enum {} {{", @@ -1445,6 +1461,7 @@ fn render_multiplexor_enums( config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?; config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?; config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?; + config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?; writeln!(w, r##"#[derive(Default)]"##)?; writeln!( w, diff --git a/testing/can-embedded/Cargo.toml b/testing/can-embedded/Cargo.toml index 9dbdbe3..c601644 100644 --- a/testing/can-embedded/Cargo.toml +++ b/testing/can-embedded/Cargo.toml @@ -11,6 +11,7 @@ build-messages = ["dep:can-messages"] [dependencies] bitvec = { version = "1.0", default-features = false } embedded-can = "0.4.1" +defmt = "0.3.8" # This is optional and default so we can turn it off for the embedded target. diff --git a/testing/can-messages/Cargo.toml b/testing/can-messages/Cargo.toml index 1a3b217..b4e357a 100644 --- a/testing/can-messages/Cargo.toml +++ b/testing/can-messages/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" bitvec = { version = "1.0", default-features = false } arbitrary = { version = "1.0", optional = true } embedded-can = "0.4.1" +defmt = "0.3.8" [build-dependencies] anyhow = "1.0" diff --git a/testing/can-messages/build.rs b/testing/can-messages/build.rs index 2f29922..5d7a7d0 100644 --- a/testing/can-messages/build.rs +++ b/testing/can-messages/build.rs @@ -19,6 +19,7 @@ fn main() -> Result<()> { .dbc_content(&dbc_file) .debug_prints(true) .impl_debug(FeatureConfig::Always) + .impl_defmt(FeatureConfig::Always) .impl_error(FeatureConfig::Gated("std")) .impl_arbitrary(FeatureConfig::Gated("arb")) .check_ranges(FeatureConfig::Always) diff --git a/testing/can-messages/src/messages.rs b/testing/can-messages/src/messages.rs index 6ee9d84..780d508 100644 --- a/testing/can-messages/src/messages.rs +++ b/testing/can-messages/src/messages.rs @@ -18,6 +18,7 @@ use arbitrary::{Arbitrary, Unstructured}; use bitvec::prelude::*; use core::ops::BitOr; +use defmt::Format; use embedded_can::{ExtendedId, Id, StandardId}; /// All messages @@ -108,7 +109,7 @@ impl Foo { /// Construct new Foo from values pub fn new(voltage: f32, current: f32) -> Result { - let mut res = Self { raw: [0u8; 4] }; + let mut res = Self { raw: [0x00; 4] }; res.set_voltage(voltage)?; res.set_current(current)?; Ok(res) @@ -306,7 +307,7 @@ impl Bar { /// Construct new Bar from values pub fn new(one: u8, two: f32, three: u8, four: u8, xtype: bool) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_one(one)?; res.set_two(two)?; res.set_three(three)?; @@ -357,7 +358,7 @@ impl Bar { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Bar::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -454,7 +455,7 @@ impl Bar { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Bar::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -507,7 +508,7 @@ impl Bar { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Bar::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -634,7 +635,7 @@ impl<'a> Arbitrary<'a> for Bar { } } /// Defined values for Three -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Debug, defmt::Format)] pub enum BarThree { Off, On, @@ -656,7 +657,7 @@ impl From for u8 { } /// Defined values for Four -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Debug, defmt::Format)] pub enum BarFour { Off, On, @@ -678,7 +679,7 @@ impl From for u8 { } /// Defined values for Type -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Debug, defmt::Format)] pub enum BarType { X0off, X1on, @@ -714,7 +715,7 @@ impl X4wd { /// Construct new _4WD from values pub fn new(x4drive: u8) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_x4drive(x4drive)?; Ok(res) } @@ -769,7 +770,7 @@ impl X4wd { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: X4wd::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -848,7 +849,7 @@ impl<'a> Arbitrary<'a> for X4wd { } } /// Defined values for _4DRIVE -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Debug, defmt::Format)] pub enum X4wd4drive { Off, X2wd, @@ -894,7 +895,7 @@ impl Amet { /// Construct new Amet from values pub fn new(one: u8, two: f32, three: u8, four: u8, five: bool) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_one(one)?; res.set_two(two)?; res.set_three(three)?; @@ -945,7 +946,7 @@ impl Amet { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Amet::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1034,7 +1035,7 @@ impl Amet { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Amet::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1079,7 +1080,7 @@ impl Amet { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: Amet::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1219,7 +1220,7 @@ impl Dolor { /// Construct new Dolor from values pub fn new(one_float: f32) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_one_float(one_float)?; Ok(res) } @@ -1350,7 +1351,7 @@ impl<'a> Arbitrary<'a> for Dolor { } } /// Defined values for OneFloat -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, PartialEq, Debug, defmt::Format)] pub enum DolorOneFloat { Dolor, Other, @@ -1396,7 +1397,7 @@ impl MultiplexTest { /// Construct new MultiplexTest from values pub fn new(multiplexor: u8, unmultiplexed_signal: u8) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_multiplexor(multiplexor)?; res.set_unmultiplexed_signal(unmultiplexed_signal)?; Ok(res) @@ -1447,7 +1448,7 @@ impl MultiplexTest { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: MultiplexTest::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1512,7 +1513,7 @@ impl MultiplexTest { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: MultiplexTest::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1593,13 +1594,13 @@ impl<'a> Arbitrary<'a> for MultiplexTest { } } /// Defined values for multiplexed signal MultiplexTest -#[derive(Debug)] +#[derive(Debug, defmt::Format)] pub enum MultiplexTestMultiplexorIndex { M0(MultiplexTestMultiplexorM0), M1(MultiplexTestMultiplexorM1), } -#[derive(Debug, Default)] +#[derive(Debug, defmt::Format, Default)] pub struct MultiplexTestMultiplexorM0 { raw: [u8; 8], } @@ -1697,7 +1698,7 @@ impl MultiplexTestMultiplexorM0 { } } -#[derive(Debug, Default)] +#[derive(Debug, defmt::Format, Default)] pub struct MultiplexTestMultiplexorM1 { raw: [u8; 8], } @@ -1828,7 +1829,7 @@ impl IntegerFactorOffset { byte_with_negative_offset: i16, byte_with_negative_min: i16, ) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_byte_with_offset(byte_with_offset)?; res.set_byte_with_factor(byte_with_factor)?; res.set_byte_with_both(byte_with_both)?; @@ -1879,7 +1880,7 @@ impl IntegerFactorOffset { } let factor = 1; let value = value.checked_sub(1).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: IntegerFactorOffset::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1924,7 +1925,7 @@ impl IntegerFactorOffset { } let factor = 4; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: IntegerFactorOffset::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -1969,7 +1970,7 @@ impl IntegerFactorOffset { } let factor = 2; let value = value.checked_sub(16).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: IntegerFactorOffset::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -2014,7 +2015,7 @@ impl IntegerFactorOffset { } let factor = 1; let value = value.checked_add(1).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: IntegerFactorOffset::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -2059,7 +2060,7 @@ impl IntegerFactorOffset { } let factor = 1; let value = value.checked_add(1).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: IntegerFactorOffset::MESSAGE_ID, })?; let value = (value / factor) as u8; @@ -2182,7 +2183,7 @@ impl NegativeFactorTest { unsigned_negative_factor_signal: i32, width_more_than_min_max: i16, ) -> Result { - let mut res = Self { raw: [0u8; 4] }; + let mut res = Self { raw: [0x00; 4] }; res.set_unsigned_negative_factor_signal(unsigned_negative_factor_signal)?; res.set_width_more_than_min_max(width_more_than_min_max)?; Ok(res) @@ -2230,7 +2231,7 @@ impl NegativeFactorTest { } let factor = -1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: NegativeFactorTest::MESSAGE_ID, })?; let value = (value / factor) as u16; @@ -2276,7 +2277,7 @@ impl NegativeFactorTest { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: NegativeFactorTest::MESSAGE_ID, })?; let value = (value / factor) as i16; @@ -2385,7 +2386,7 @@ impl LargerIntsWithOffsets { /// Construct new LargerIntsWithOffsets from values pub fn new(twelve: i16, sixteen: i32) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_twelve(twelve)?; res.set_sixteen(sixteen)?; Ok(res) @@ -2438,7 +2439,7 @@ impl LargerIntsWithOffsets { let value = value .checked_add(1000) .ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: LargerIntsWithOffsets::MESSAGE_ID, })?; let value = (value / factor) as u16; @@ -2487,7 +2488,7 @@ impl LargerIntsWithOffsets { let value = value .checked_add(1000) .ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: LargerIntsWithOffsets::MESSAGE_ID, })?; let value = (value / factor) as u16; @@ -2586,7 +2587,7 @@ impl MsgWithoutSignals { /// Construct new MsgWithoutSignals from values pub fn new() -> Result { - let res = Self { raw: [0u8; 8] }; + let res = Self { raw: [0x00; 8] }; Ok(res) } @@ -2682,7 +2683,7 @@ impl TruncatedBeSignal { /// Construct new TruncatedBeSignal from values pub fn new(foo: i16) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_foo(foo)?; Ok(res) } @@ -2730,7 +2731,7 @@ impl TruncatedBeSignal { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: TruncatedBeSignal::MESSAGE_ID, })?; let value = (value / factor) as i16; @@ -2829,7 +2830,7 @@ impl TruncatedLeSignal { /// Construct new TruncatedLeSignal from values pub fn new(foo: i16) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_foo(foo)?; Ok(res) } @@ -2877,7 +2878,7 @@ impl TruncatedLeSignal { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: TruncatedLeSignal::MESSAGE_ID, })?; let value = (value / factor) as i16; @@ -2976,7 +2977,7 @@ impl MsgExtendedId { /// Construct new MsgExtendedId from values pub fn new(dummy: u8) -> Result { - let mut res = Self { raw: [0u8; 8] }; + let mut res = Self { raw: [0x00; 8] }; res.set_dummy(dummy)?; Ok(res) } @@ -3023,7 +3024,7 @@ impl MsgExtendedId { } let factor = 1; let value = value.checked_sub(0).ok_or(CanError::ParameterOutOfRange { - message_id: Self::MESSAGE_ID, + message_id: MsgExtendedId::MESSAGE_ID, })?; let value = (value / factor) as u8;