zbus

This is the main subcrate of the [zbus] project, that provides the main API you will use to interact with D-Bus from Rust. It takes care of the establishment of a connection, the creation, sending and receiving of different kind of D-Bus messages (method calls, signals etc) for you.

Status: Stable.

Getting Started

The best way to get started with zbus is the book, where we start with basic D-Bus concepts and explain with code samples, how zbus makes D-Bus easy.

Example code

Client

This code display a notification on your Freedesktop.org-compatible OS:

```rust,no_run use std::{collections::HashMap, error::Error};

use zbus::{Connection, dbus_proxy}; use zvariant::Value;

[dbus_proxy(

interface = "org.freedesktop.Notifications",
default_service = "org.freedesktop.Notifications",
default_path = "/org/freedesktop/Notifications"

)] trait Notifications { fn notify( &self, appname: &str, replacesid: u32, appicon: &str, summary: &str, body: &str, actions: &[&str], hints: &HashMap<&str, &Value<'>>, expire_timeout: i32, ) -> zbus::Result; }

// Although we use async-std here, you can use any async runtime of choice.

[async_std::main]

async fn main() -> Result<(), Box> { let connection = Connection::session().await?;

// `dbus_proxy` macro creates `NotificationProxy` based on `Notifications` trait.
let proxy = NotificationsProxy::new(&connection).await?;
let reply = proxy.notify(
    "my-app",
    0,
    "dialog-information",
    "A summary",
    "Some body",
    &[],
    &HashMap::new(),
    5000,
).await?;
dbg!(reply);

Ok(())

} ```

Server

A simple service that politely greets whoever calls its SayHello method:

```rust,norun use std::{ error::Error, thread::sleep, time::Duration, }; use zbus::{ObjectServer, ConnectionBuilder, dbusinterface, fdo};

struct Greeter { count: u64 }

[dbus_interface(name = "org.zbus.MyGreeter1")]

impl Greeter { // Can be async as well. fn say_hello(&mut self, name: &str) -> String { self.count += 1; format!("Hello {}! I have been called: {}", name, self.count) } }

// Although we use async-std here, you can use any async runtime of choice.

[async_std::main]

async fn main() -> Result<(), Box> { let greeter = Greeter { count: 0 }; let _ = ConnectionBuilder::session()? .name("org.zbus.MyGreeter")? .serve_at("/org/zbus/MyGreeter", greeter)? .build() .await?;

// Do other things or go to sleep.
sleep(Duration::from_secs(60));

Ok(())

} ```

You can use the following command to test it:

bash $ busctl --user call org.zbus.MyGreeter /org/zbus/MyGreeter org.zbus.MyGreeter1 SayHello s "Maria" Hello Maria! s

Blocking API

While zbus is primarily asynchronous (since 2.0), blocking wrappers are provided for convenience.

Compatibility with async runtimes

zbus is runtime-agnostic and should work out of the box with different Rust async runtimes. However, in order to achieve that, zbus spawns a thread per connection to handle various internal tasks. If that is something you would like to avoid, you need to: * Use [ConnectionBuilder] and disable the internal_executor flag. * Ensure the internal executor keeps ticking continuously.