Attribute Macro zbus_macros::dbus_proxy [−][src]
#[dbus_proxy]
Expand description
Attribute macro for defining D-Bus proxies (using zbus::Proxy
and zbus::azync::Proxy
).
The macro must be applied on a trait T
. Two matching impl T
will provide a synchronous Proxy
implementation, named TraitNameProxy
and an asynchronous one, named AsyncTraitNameProxy
. The
proxy instances can be created with the associated new()
or builder()
methods. The former
doesn’t take any argument and uses the default service name and path. The later allows you to
specify non-default proxy arguments.
Each trait method will be expanded to call to the associated D-Bus remote interface.
Trait methods accept dbus_proxy
attributes:
-
name
- override the D-Bus name (pascal case form by default) -
property
- expose the method as a property. If the method takes an argument, it must be a setter, with aset_
prefix. Otherwise, it’s a getter. -
signal
- declare a signal just like a D-Bus method. The macro will provide a method to register and deregister a handler for the signal, whose signature must match that of the signature declaration. -
object
- methods that returns anObjectPath
can be annotated with theobject
attribute to specify the proxy object to be constructed from the returnedObjectPath
.NB: Any doc comments provided shall be appended to the ones added by the macro.
Example
use zbus_macros::dbus_proxy; use zbus::{Connection, Result, fdo}; use zvariant::Value; use futures_util::future::FutureExt; use async_io::block_on; #[dbus_proxy( interface = "org.test.SomeIface", default_service = "org.test.SomeService", default_path = "/org/test/SomeObject" )] trait SomeIface { fn do_this(&self, with: &str, some: u32, arg: &Value<'_>) -> Result<bool>; #[dbus_proxy(property)] fn a_property(&self) -> fdo::Result<String>; #[dbus_proxy(property)] fn set_a_property(&self, a_property: &str) -> fdo::Result<()>; #[dbus_proxy(signal)] fn some_signal(&self, arg1: &str, arg2: u32) -> fdo::Result<()>; #[dbus_proxy(object = "SomeOtherIface")] // The method will return a `SomeOtherIfaceProxy` or `AsyncSomeOtherIfaceProxy`, depending on // whether it is called on `SomeIfaceProxy` or `AsyncSomeIfaceProxy`, respectively. fn some_method(&self, arg1: &str); }; #[dbus_proxy( interface = "org.test.SomeOtherIface", default_service = "org.test.SomeOtherService" )] trait SomeOtherIface {} let connection = Connection::session()?; // Use `builder` to override the default arguments, `new` otherwise. let proxy = SomeIfaceProxy::builder(&connection) .destination("org.another.Service")? .cache_properties(false) .build()?; let _ = proxy.do_this("foo", 32, &Value::new(true)); let _ = proxy.set_a_property("val"); let handler_id = proxy.connect_some_signal(|s, u| { println!("arg1: {}, arg2: {}", s, u); Ok(()) })?; // You'll want to make at least a call to `handle_next_signal` before disconnecting the signal. assert!(proxy.disconnect_signal(handler_id)?); assert!(!proxy.disconnect_signal(handler_id)?); // Now the same again, but asynchronous. block_on(async move { let proxy = AsyncSomeIfaceProxy::builder(&connection.into()) .cache_properties(false) .build() .await .unwrap(); let _ = proxy.do_this("foo", 32, &Value::new(true)).await; let _ = proxy.set_a_property("val").await; let handler_id = proxy.connect_some_signal(|s, u| { println!("arg1: {}, arg2: {}", s, u); async { Ok(()) }.boxed() }).await?; // You'll want to make at least a call to `handle_next_signal` before disconnecting the signal. assert!(proxy.disconnect_signal(handler_id).await?); assert!(!proxy.disconnect_signal(handler_id).await?); Ok::<(), zbus::Error>(()) })?;
zbus_polkit
is a good example of how to bind a real D-Bus API.