Skip to content

Commit

Permalink
Merge pull request #91 from projectgus/feature/defmt
Browse files Browse the repository at this point in the history
Add optional defmt::Format support for generated types.
  • Loading branch information
linusharberg authored Dec 2, 2024
2 parents ee528bd + bb4e74a commit 5b9d3d0
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 12 deletions.
95 changes: 93 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
60 changes: 60 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,9 @@ 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 +437,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 +993,9 @@ 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 +1397,48 @@ 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 +1470,9 @@ 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,9 @@ 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
2 changes: 1 addition & 1 deletion testing/can-embedded/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +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.
# Then it doesn't pull in std.
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 5b9d3d0

Please sign in to comment.