Skip to content
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
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ jobs:
sed -e s/UID/$UID/ -e s/PATH/path/ CI/dbus-session.conf > /tmp/dbus-session.conf
sed -e s/UID/$UID/ -e s/PATH/abstract/ CI/dbus-session.conf > /tmp/dbus-session-abstract.conf
sudo apt-get install -y dbus
sudo apt-get install -y ibus
ibus start &
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
Expand All @@ -83,7 +85,7 @@ jobs:
dbus-run-session --config-file /tmp/dbus-session-abstract.conf -- cargo --locked test --profile "$PROFILE" --verbose -- basic_connection
# All features except tokio.
dbus-run-session --config-file /tmp/dbus-session.conf -- \
cargo --locked test --profile "$PROFILE" --verbose --features uuid,url,time,chrono,option-as-array,vsock,bus-impl \
cargo --locked test --profile "$PROFILE" --verbose --features uuid,url,time,chrono,option-as-array,vsock,bus-impl,ibus \
-- --skip fdpass_systemd
# Test tokio support.
dbus-run-session --config-file /tmp/dbus-session.conf -- \
Expand Down
2 changes: 2 additions & 0 deletions zbus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ camino = ["zvariant/camino"]
bus-impl = ["p2p"]
# Enables API that is only needed for peer-to-peer (p2p) connections.
p2p = ["dep:rand"]
# Enables API that is only needed for IBus Daemon.
ibus = []
async-io = [
"dep:async-io",
"async-executor",
Expand Down
8 changes: 8 additions & 0 deletions zbus/src/blocking/connection/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ impl<'a> Builder<'a> {
crate::connection::Builder::system().map(Self)
}

/// Create a builder for the [IBus] daemon.
///
/// [IBus]: https://en.wikipedia.org/wiki/Intelligent_Input_Bus
#[cfg(feature = "ibus")]
pub fn ibus() -> Result<Self> {
block_on(crate::connection::Builder::ibus()).map(Self)
}

/// Create a builder for a connection that will use the given [D-Bus bus address].
///
/// [D-Bus bus address]: https://dbus.freedesktop.org/doc/dbus-specification.html#addresses
Expand Down
35 changes: 35 additions & 0 deletions zbus/src/connection/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use static_assertions::assert_impl_all;
use std::net::TcpStream;
#[cfg(all(unix, not(feature = "tokio")))]
use std::os::unix::net::UnixStream;
#[cfg(feature = "ibus")]
use std::process::Stdio;
use std::{
collections::{HashMap, HashSet},
vec,
Expand All @@ -23,6 +25,9 @@ use vsock::VsockStream;

use zvariant::ObjectPath;

#[cfg(feature = "ibus")]
use crate::process::Command;

use crate::{
address::{self, Address},
names::{InterfaceName, WellKnownName},
Expand Down Expand Up @@ -85,6 +90,36 @@ impl<'a> Builder<'a> {
Ok(Self::new(Target::Address(Address::system()?)))
}

/// Create a builder for the [IBus] daemon.
///
/// [IBus]: https://en.wikipedia.org/wiki/Intelligent_Input_Bus
#[cfg(feature = "ibus")]
pub async fn ibus() -> Result<Self> {
let child_process = Command::new("ibus")
.args(["address"])
.stdout(Stdio::piped())
.spawn()
.expect("Fail to call `ibus address`");

#[cfg(not(feature = "tokio"))]
let output = child_process
.output()
.await
.expect("Fail to run `ibus address`");

#[cfg(feature = "tokio")]
let output = child_process
.wait_with_output()
.await
.expect("Fail to run `ibus address`");
Comment on lines +104 to +114
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just noticed this part. Why do they need to be different? tokio::process::Command also has output method, which should be good enough for us?

Actually, abstractions::process::Command::output can do most stuff already for us here? 🤔 You don't even need to bother with piping etc.


let ibus_address = std::str::from_utf8(&output.stdout)
.expect("Invalid utf8 when getting stdout")
.trim();

Builder::address(ibus_address)
}

/// Create a builder for a connection that will use the given [D-Bus bus address].
///
/// # Example
Expand Down
13 changes: 13 additions & 0 deletions zbus/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,19 @@ async fn fdpass_systemd_async() {
f.metadata().unwrap();
}

#[cfg(all(target_os = "linux", feature = "ibus"))]
#[test]
fn ibus() {
use zbus::blocking;

let ibus_blocking = blocking::connection::Builder::ibus()
.unwrap()
.build()
.unwrap();

assert!(!ibus_blocking.server_guid().is_empty());
}

#[test]
#[instrument]
#[timeout(15000)]
Expand Down