From 1fcce0208c8a2363b3d3986f33848d821380f301 Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Thu, 18 Apr 2024 21:07:38 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20zx:=20Prevent=20collisions=20bet?= =?UTF-8?q?ween=20methods,=20signals=20and=20properties?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a collision is detected and additional `_` is appended to the identifier until there is no more collision. Signed-off-by: Pascal Bach --- zbus_xmlgen/src/lib.rs | 29 +++++++++++++++++++---- zbus_xmlgen/tests/data/sample_object0.rs | 22 +++++++++++++++++ zbus_xmlgen/tests/data/sample_object0.xml | 8 +++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/zbus_xmlgen/src/lib.rs b/zbus_xmlgen/src/lib.rs index 1d2c8f359..66039d7a5 100644 --- a/zbus_xmlgen/src/lib.rs +++ b/zbus_xmlgen/src/lib.rs @@ -1,5 +1,6 @@ use snakecase::ascii::to_snakecase; use std::{ + collections::HashMap, error::Error, fmt::{Display, Formatter, Write}, process::{Command, Stdio}, @@ -172,11 +173,14 @@ impl<'i> GenTrait<'i> { writeln!(w, ")]")?; writeln!(w, "trait {name} {{")?; + let mut collision_hander = CollisionHandler::default(); + let mut methods = iface.methods().to_vec(); methods.sort_by(|a, b| a.name().partial_cmp(&b.name()).unwrap()); for m in &methods { let (inputs, output) = inputs_output_from_args(m.args()); - let name = to_identifier(&to_snakecase(m.name().as_str())); + let name = + collision_hander.avoid_collision(to_identifier(&to_snakecase(m.name().as_str()))); writeln!(w)?; writeln!(w, " /// {} method", m.name())?; if pascal_case(&name) != m.name().as_str() { @@ -190,7 +194,8 @@ impl<'i> GenTrait<'i> { signals.sort_by(|a, b| a.name().partial_cmp(&b.name()).unwrap()); for signal in &signals { let args = parse_signal_args(signal.args()); - let name = to_identifier(&to_snakecase(signal.name().as_str())); + let name = collision_hander + .avoid_collision(to_identifier(&to_snakecase(signal.name().as_str()))); writeln!(w)?; writeln!(w, " /// {} signal", signal.name())?; if pascal_case(&name) != signal.name().as_str() { @@ -214,18 +219,20 @@ impl<'i> GenTrait<'i> { writeln!(w)?; writeln!(w, " /// {} property", p.name())?; if p.access().read() { + let getter_name = collision_hander.avoid_collision(name.clone()); writeln!(w, "{}", fn_attribute)?; let output = to_rust_type(p.ty(), false, false); hide_clippy_type_complexity_lint(w, p.ty().signature())?; - writeln!(w, " fn {name}(&self) -> zbus::Result<{output}>;",)?; + writeln!(w, " fn {getter_name}(&self) -> zbus::Result<{output}>;",)?; } if p.access().write() { + let setter_name = collision_hander.avoid_collision(format!("set_{}", &name)); writeln!(w, "{}", fn_attribute)?; let input = to_rust_type(p.ty(), true, true); writeln!( w, - " fn set_{name}(&self, value: {input}) -> zbus::Result<()>;", + " fn {setter_name}(&self, value: {input}) -> zbus::Result<()>;", )?; } } @@ -437,6 +444,20 @@ fn to_identifier(id: &str) -> String { } } +#[derive(Default)] +struct CollisionHandler { + used_identifiers: HashMap, +} + +impl CollisionHandler { + fn avoid_collision(&mut self, identifier: String) -> String { + let use_count = self.used_identifiers.entry(identifier.clone()).or_default(); + let new_identifier = format!("{}{}", &identifier, "_".repeat(*use_count)); + *use_count += 1; + new_identifier + } +} + // This function is the same as zbus_macros::utils::pascal_case pub fn pascal_case(s: &str) -> String { let mut pascal = String::new(); diff --git a/zbus_xmlgen/tests/data/sample_object0.rs b/zbus_xmlgen/tests/data/sample_object0.rs index b232ade39..8ed58b5dd 100644 --- a/zbus_xmlgen/tests/data/sample_object0.rs +++ b/zbus_xmlgen/tests/data/sample_object0.rs @@ -45,6 +45,12 @@ trait SampleInterface0 { calypso: &zbus::zvariant::Value<'_>, ) -> zbus::Result<()>; + /// SetWallMessage method + fn set_wall_message(&self) -> zbus::Result<()>; + + /// State method + fn state(&self) -> zbus::Result<()>; + /// Changed signal #[zbus(signal)] fn changed(&self, new_value: bool) -> zbus::Result<()>; @@ -68,6 +74,10 @@ trait SampleInterface0 { #[zbus(signal)] fn signal_value(&self, value: zbus::zvariant::Value<'_>) -> zbus::Result<()>; + /// State signal + #[zbus(signal)] + fn state_(&self) -> zbus::Result<()>; + /// Bar property #[zbus(property)] fn bar(&self) -> zbus::Result; @@ -94,4 +104,16 @@ trait SampleInterface0 { std::collections::HashMap, )>, >; + + /// State property + #[zbus(property)] + fn state__(&self) -> zbus::Result; + #[zbus(property)] + fn set_state(&self, value: u8) -> zbus::Result<()>; + + /// WallMessage property + #[zbus(property)] + fn wall_message(&self) -> zbus::Result; + #[zbus(property)] + fn set_wall_message_(&self, value: u8) -> zbus::Result<()>; } diff --git a/zbus_xmlgen/tests/data/sample_object0.xml b/zbus_xmlgen/tests/data/sample_object0.xml index c17b27a2a..4dc29d0c6 100644 --- a/zbus_xmlgen/tests/data/sample_object0.xml +++ b/zbus_xmlgen/tests/data/sample_object0.xml @@ -36,6 +36,10 @@ + + + + @@ -52,9 +56,13 @@ + + + +