Skip to content

Commit

Permalink
Merge pull request #409 from Kijewski/pr-less-async_recursion
Browse files Browse the repository at this point in the history
➖ zbus: use less `async-recursion`
  • Loading branch information
zeenix authored Jul 24, 2023
2 parents fe457ea + e64e7cd commit 3fbf2ae
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 35 deletions.
4 changes: 3 additions & 1 deletion zbus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ rand = "0.8.5"
sha1 = { version = "0.10.5", features = ["std"] }
event-listener = "2.5.3"
static_assertions = "1.1.0"
async-recursion = "1.0.0"
async-trait = "0.1.58"
async-fs = { version = "1.6.0", optional = true }
# FIXME: We should only enable process feature for Mac OS. See comment on async-process below for why we can't.
Expand Down Expand Up @@ -87,6 +86,9 @@ nix = { version = "0.26.0", default-features = false, features = ["socket", "uio
# Cargo doesn't provide a way to do that for only specific target OS: https://github.com/rust-lang/cargo/issues/1197.
async-process = "1.7.0"

[target.'cfg(any(target_os = "macos", windows))'.dependencies]
async-recursion = "1.0.0"

[dev-dependencies]
doc-comment = "0.3.3"
futures-util = "0.3.25" # activate default features
Expand Down
2 changes: 1 addition & 1 deletion zbus/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ pub(crate) async fn macos_launchd_bus_address(env_key: &str) -> Result<Address>
}

impl Address {
#[async_recursion::async_recursion]
#[cfg_attr(any(target_os = "macos", windows), async_recursion::async_recursion)]
pub(crate) async fn connect(self) -> Result<Stream> {
match self {
Address::Unix(p) => {
Expand Down
67 changes: 34 additions & 33 deletions zbus/src/object_server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use event_listener::{Event, EventListener};
use serde::Serialize;
use std::{
collections::{hash_map::Entry, HashMap},
collections::{hash_map::Entry, HashMap, VecDeque},
convert::TryInto,
fmt::Write,
marker::PhantomData,
Expand Down Expand Up @@ -288,55 +288,56 @@ impl Node {
true
}

#[async_recursion::async_recursion]
async fn introspect_to_writer<W: Write + Send>(&self, writer: &mut W, level: usize) {
if level == 0 {
writeln!(
writer,
r#"
async fn introspect_to_writer<W: Write + Send>(&self, writer: &mut W) {
let mut node_list = VecDeque::new();
node_list.push_back((self, "", 0));
while let Some((node, path, level)) = node_list.pop_front() {
if level == 0 {
writeln!(
writer,
r#"
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>"#
)
.unwrap();
}
)
.unwrap();
} else {
writeln!(
writer,
"{:indent$}<node name=\"{}\">",
"",
path,
indent = level
)
.unwrap();
}

for iface in self.interfaces.values() {
iface.read().await.introspect_to_writer(writer, level + 2);
}
for iface in node.interfaces.values() {
iface.read().await.introspect_to_writer(writer, level + 2);
}

for (path, node) in &self.children {
let level = level + 2;
writeln!(
writer,
"{:indent$}<node name=\"{}\">",
"",
path,
indent = level
)
.unwrap();
node.introspect_to_writer(writer, level).await;
writeln!(writer, "{:indent$}</node>", "", indent = level).unwrap();
}
for (path, node) in &node.children {
node_list.push_front((node, path, level + 2));
}

if level == 0 {
writeln!(writer, "</node>").unwrap();
writeln!(writer, "{:indent$}</node>", "", indent = level).unwrap();
}
}

pub(crate) async fn introspect(&self) -> String {
let mut xml = String::with_capacity(1024);

self.introspect_to_writer(&mut xml, 0).await;
self.introspect_to_writer(&mut xml).await;

xml
}

#[async_recursion::async_recursion]
pub(crate) async fn get_managed_objects(&self) -> ManagedObjects {
// Recursively get all properties of all interfaces of descendants.
let mut managed_objects = ManagedObjects::new();
for node in self.children.values() {

// Recursively get all properties of all interfaces of descendants.
let mut node_list: Vec<_> = self.children.values().collect();
while let Some(node) = node_list.pop() {
let mut interfaces = HashMap::new();
for iface_name in node.interfaces.keys().filter(|n| {
// Filter standard interfaces.
Expand All @@ -349,7 +350,7 @@ impl Node {
interfaces.insert(iface_name.clone().into(), props);
}
managed_objects.insert(node.path.clone(), interfaces);
managed_objects.extend(node.get_managed_objects().await);
node_list.extend(node.children.values());
}

managed_objects
Expand Down

0 comments on commit 3fbf2ae

Please sign in to comment.