Skip to content

Commit

Permalink
Add optional defmt::Format support for generated types
Browse files Browse the repository at this point in the history
- Derived for enum types
- Formats messages by printing individual field values
- Enabled in can-messages test generation.
  • Loading branch information
projectgus committed Nov 9, 2024
1 parent af7cbf3 commit 605f846
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 11 deletions.
94 changes: 92 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ heck = "0.4.0"
typed-builder = "0.18.0"
embedded-can = "0.4.1"

[dev-dependencies]
defmt = "0.3.8"

[workspace]
members = [
".",
Expand Down
58 changes: 58 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ pub struct Config<'a> {
#[builder(default)]
pub impl_debug: FeatureConfig<'a>,

/// Optional: `impl defmt::Format` for generated types. Default: `Never`.
#[builder(default)]
pub impl_defmt: FeatureConfig<'a>,

/// Optional: `impl Arbitrary` for generated types. Default: `Never`.
#[builder(default)]
pub impl_arbitrary: FeatureConfig<'a>,
Expand Down Expand Up @@ -189,6 +193,7 @@ fn render_root_enum(mut w: impl Write, dbc: &DBC, config: &Config<'_>) -> Result
writeln!(w, "/// All messages")?;
writeln!(w, "#[derive(Clone)]")?;
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
writeln!(w, "pub enum Messages {{")?;
Expand Down Expand Up @@ -430,6 +435,8 @@ fn render_message(mut w: impl Write, config: &Config<'_>, msg: &Message, dbc: &D

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

render_defmt_impl(&mut w, config, msg)?;

render_arbitrary(&mut w, config, msg)?;

let enums_for_this_message = dbc.value_descriptions().iter().filter_map(|x| {
Expand Down Expand Up @@ -984,6 +991,7 @@ fn write_enum(
writeln!(w, "/// Defined values for {}", signal.name())?;
writeln!(w, "#[derive(Clone, Copy, PartialEq)]")?;
config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
writeln!(w, "pub enum {} {{", type_name)?;
Expand Down Expand Up @@ -1385,6 +1393,54 @@ fn render_debug_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> R
Ok(())
}

fn render_defmt_impl(mut w: impl Write, config: &Config<'_>, msg: &Message) -> Result<()> {
match &config.impl_defmt {
FeatureConfig::Always => {}
FeatureConfig::Gated(gate) => writeln!(w, r##"#[cfg(feature = {gate:?})]"##)?,
FeatureConfig::Never => return Ok(()),
}

let typ = type_name(msg.message_name());
writeln!(w, r##"impl defmt::Format for {} {{"##, typ)?;
{
let mut w = PadAdapter::wrap(&mut w);
writeln!(
w,
"fn format(&self, f: defmt::Formatter) {{"
)?;
{
let mut w = PadAdapter::wrap(&mut w);
writeln!(w, r#"defmt::write!(f,"#)?;
{
let mut w = PadAdapter::wrap(&mut w);
write!(w, r#""{} {{{{"#, typ)?;
{
for signal in msg.signals() {
if *signal.multiplexer_indicator() == MultiplexIndicator::Plain {
write!(w,
r#" {}={{:?}}"#,
signal.name(),
)?;
}
}
}
writeln!(w, r#" }}}}","#)?;

for signal in msg.signals() {
if *signal.multiplexer_indicator() == MultiplexIndicator::Plain {
writeln!(w, "self.{}(),", field_name(signal.name()))?;
}
}
writeln!(w, r#");"#)?;
}
writeln!(w, "}}")?;
}
}
writeln!(w, "}}")?;
writeln!(w)?;
Ok(())
}

fn render_multiplexor_enums(
mut w: impl Write,
config: &Config<'_>,
Expand Down Expand Up @@ -1416,6 +1472,7 @@ fn render_multiplexor_enums(
)?;

config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
writeln!(
Expand Down Expand Up @@ -1443,6 +1500,7 @@ fn render_multiplexor_enums(
let struct_name = multiplexed_enum_variant_name(msg, multiplexor_signal, **switch_index)?;

config.impl_debug.fmt_attr(&mut w, "derive(Debug)")?;
config.impl_defmt.fmt_attr(&mut w, "derive(defmt::Format)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Serialize)")?;
config.impl_serde.fmt_attr(&mut w, "derive(Deserialize)")?;
writeln!(w, r##"#[derive(Default)]"##)?;
Expand Down
1 change: 1 addition & 0 deletions testing/can-messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions testing/can-messages/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 605f846

Please sign in to comment.