Skip to content

Commit bb4e74a

Browse files
committed
Add optional defmt::Format support for generated types
- Derived for enum types - Formats messages by printing individual field values - Enabled in can-messages test generation.
1 parent af7cbf3 commit bb4e74a

File tree

7 files changed

+288
-12
lines changed

7 files changed

+288
-12
lines changed

Cargo.lock

Lines changed: 93 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ heck = "0.4.0"
2424
typed-builder = "0.18.0"
2525
embedded-can = "0.4.1"
2626

27+
[dev-dependencies]
28+
defmt = "0.3.8"
29+
2730
[workspace]
2831
members = [
2932
".",

src/lib.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ pub struct Config<'a> {
6060
#[builder(default)]
6161
pub impl_debug: FeatureConfig<'a>,
6262

63+
/// Optional: `impl defmt::Format` for generated types. Default: `Never`.
64+
#[builder(default)]
65+
pub impl_defmt: FeatureConfig<'a>,
66+
6367
/// Optional: `impl Arbitrary` for generated types. Default: `Never`.
6468
#[builder(default)]
6569
pub impl_arbitrary: FeatureConfig<'a>,
@@ -189,6 +193,9 @@ fn render_root_enum(mut w: impl Write, dbc: &DBC, config: &Config<'_>) -> Result
189193
writeln!(w, "/// All messages")?;
190194
writeln!(w, "#[derive(Clone)]")?;
191195
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
196+
config
197+
.impl_defmt
198+
.fmt_attr(&mut w, "derive(defmt::Format)")?;
192199
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
193200
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
194201
writeln!(w, "pub enum Messages {{")?;
@@ -430,6 +437,8 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D
430437

431438
render_debug_impl(&mut w, config, msg)?;
432439

440+
render_defmt_impl(&mut w, config, msg)?;
441+
433442
render_arbitrary(&mut w, config, msg)?;
434443

435444
let enums_for_this_message = dbc.value_descriptions().iter().filter_map(|x| {
@@ -984,6 +993,9 @@ fn write_enum(
984993
writeln!(w, "/// Defined values for {}", signal.name())?;
985994
writeln!(w, "#[derive(Clone, Copy, PartialEq)]")?;
986995
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
996+
config
997+
.impl_defmt
998+
.fmt_attr(&mut w, "derive(defmt::Format)")?;
987999
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
9881000
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
9891001
writeln!(w, "pub enum {} {{", type_name)?;
@@ -1385,6 +1397,48 @@ fn render_debug_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> R
13851397
Ok(())
13861398
}
13871399

1400+
fn render_defmt_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> Result<()> {
1401+
match &config.impl_defmt {
1402+
FeatureConfig::Always => {}
1403+
FeatureConfig::Gated(gate) => writeln!(w, r##"#[cfg(feature = {gate:?})]"##)?,
1404+
FeatureConfig::Never => return Ok(()),
1405+
}
1406+
1407+
let typ = type_name(msg.message_name());
1408+
writeln!(w, r##"impl defmt::Format for {} {{"##, typ)?;
1409+
{
1410+
let mut w = PadAdapter::wrap(&mut w);
1411+
writeln!(w, "fn format(&self, f: defmt::Formatter) {{")?;
1412+
{
1413+
let mut w = PadAdapter::wrap(&mut w);
1414+
writeln!(w, r#"defmt::write!(f,"#)?;
1415+
{
1416+
let mut w = PadAdapter::wrap(&mut w);
1417+
write!(w, r#""{} {{{{"#, typ)?;
1418+
{
1419+
for signal in msg.signals() {
1420+
if *signal.multiplexer_indicator() == MultiplexIndicator::Plain {
1421+
write!(w, r#" {}={{:?}}"#, signal.name(),)?;
1422+
}
1423+
}
1424+
}
1425+
writeln!(w, r#" }}}}","#)?;
1426+
1427+
for signal in msg.signals() {
1428+
if *signal.multiplexer_indicator() == MultiplexIndicator::Plain {
1429+
writeln!(w, "self.{}(),", field_name(signal.name()))?;
1430+
}
1431+
}
1432+
writeln!(w, r#");"#)?;
1433+
}
1434+
writeln!(w, "}}")?;
1435+
}
1436+
}
1437+
writeln!(w, "}}")?;
1438+
writeln!(w)?;
1439+
Ok(())
1440+
}
1441+
13881442
fn render_multiplexor_enums(
13891443
mut w: impl Write,
13901444
config: &Config<'_>,
@@ -1416,6 +1470,9 @@ fn render_multiplexor_enums(
14161470
)?;
14171471

14181472
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
1473+
config
1474+
.impl_defmt
1475+
.fmt_attr(&mut w, "derive(defmt::Format)")?;
14191476
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
14201477
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
14211478
writeln!(
@@ -1443,6 +1500,9 @@ fn render_multiplexor_enums(
14431500
let struct_name = multiplexed_enum_variant_name(msg, multiplexor_signal, **switch_index)?;
14441501

14451502
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
1503+
config
1504+
.impl_defmt
1505+
.fmt_attr(&mut w, "derive(defmt::Format)")?;
14461506
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
14471507
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
14481508
writeln!(w, r##"#[derive(Default)]"##)?;

testing/can-embedded/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ build-messages = ["dep:can-messages"]
1111
[dependencies]
1212
bitvec = { version = "1.0", default-features = false }
1313
embedded-can = "0.4.1"
14-
14+
defmt = "0.3.8"
1515

1616
# This is optional and default so we can turn it off for the embedded target.
1717
# Then it doesn't pull in std.

testing/can-messages/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
bitvec = { version = "1.0", default-features = false }
99
arbitrary = { version = "1.0", optional = true }
1010
embedded-can = "0.4.1"
11+
defmt = "0.3.8"
1112

1213
[build-dependencies]
1314
anyhow = "1.0"

testing/can-messages/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ fn main() -> Result<()> {
1919
.dbc_content(&dbc_file)
2020
.debug_prints(true)
2121
.impl_debug(FeatureConfig::Always)
22+
.impl_defmt(FeatureConfig::Always)
2223
.impl_error(FeatureConfig::Gated("std"))
2324
.impl_arbitrary(FeatureConfig::Gated("arb"))
2425
.check_ranges(FeatureConfig::Always)

0 commit comments

Comments
 (0)