Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 zx: Prevent collisions between methods, signals and properties #722

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions zbus_xmlgen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use snakecase::ascii::to_snakecase;
use std::{
collections::HashMap,
error::Error,
fmt::{Display, Formatter, Write},
process::{Command, Stdio},
Expand Down Expand Up @@ -172,11 +173,13 @@ impl<'i> GenTrait<'i> {
writeln!(w, ")]")?;
writeln!(w, "trait {name} {{")?;

let mut identifiers = Identifier::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 = identifiers.make_unique(&to_identifier(&to_snakecase(m.name().as_str())));
writeln!(w)?;
writeln!(w, " /// {} method", m.name())?;
if pascal_case(&name) != m.name().as_str() {
Expand All @@ -190,7 +193,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 =
identifiers.make_unique(&to_identifier(&to_snakecase(signal.name().as_str())));
writeln!(w)?;
writeln!(w, " /// {} signal", signal.name())?;
if pascal_case(&name) != signal.name().as_str() {
Expand All @@ -214,18 +218,20 @@ impl<'i> GenTrait<'i> {
writeln!(w)?;
writeln!(w, " /// {} property", p.name())?;
if p.access().read() {
let getter_name = identifiers.make_unique(&name);
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 = identifiers.make_unique(&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<()>;",
)?;
}
}
Expand Down Expand Up @@ -437,6 +443,23 @@ fn to_identifier(id: &str) -> String {
}
}

#[derive(Default)]
struct Identifier {
used_identifiers: HashMap<String, usize>,
}

impl Identifier {
fn make_unique(&mut self, identifier: &str) -> String {
let use_count = self
.used_identifiers
.entry(identifier.to_owned())
.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();
Expand Down
22 changes: 22 additions & 0 deletions zbus_xmlgen/tests/data/sample_object0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()>;
Expand All @@ -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<u8>;
Expand All @@ -94,4 +104,16 @@ trait SampleInterface0 {
std::collections::HashMap<String, zbus::zvariant::OwnedValue>,
)>,
>;

/// State property
#[zbus(property)]
fn state__(&self) -> zbus::Result<u8>;
#[zbus(property)]
fn set_state(&self, value: u8) -> zbus::Result<()>;

/// WallMessage property
#[zbus(property)]
fn wall_message(&self) -> zbus::Result<u8>;
#[zbus(property)]
fn set_wall_message_(&self, value: u8) -> zbus::Result<()>;
}
8 changes: 8 additions & 0 deletions zbus_xmlgen/tests/data/sample_object0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
<arg name="polyphemus" type="i"/>
<arg name="calypso" type="v"/>
</method>
<method name="SetWallMessage">
</method>
<method name="State">
</method>
<signal name="Changed">
<arg name="new_value" type="b"/>
</signal>
Expand All @@ -52,9 +56,13 @@
<signal name="SignalDictStringToValue">
<arg type="a{sv}" name="dict"/>
</signal>
<signal name="State">
</signal>
<property name="Bar" type="y" access="readwrite"/>
<property name="Foo-Bar" type="y" access="readwrite"/>
<property name="Matryoshkas" type="a(oiasta{sv})" access="read"/>
<property name="WallMessage" type="y" access="readwrite"/>
<property name="State" type="y" access="readwrite"/>
</interface>
<node name="child_of_sample_object"/>
<node name="another_child_of_sample_object"/>
Expand Down