Attribute Macro zbus::dbus_interface
source · #[dbus_interface]
Expand description
Attribute macro for implementing a D-Bus interface.
The macro must be applied on an impl T
. All methods will be exported, either as methods,
properties or signal depending on the item attributes. It will implement the Interface
trait
for T
on your behalf, to handle the message dispatching and introspection support.
The methods accepts the dbus_interface
attributes:
-
name
- override the D-Bus name (pascal case form of the method 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. If it may fail, a property method must returnzbus::fdo::Result
. -
signal
- the method is a “signal”. It must be a method declaration (without body). Its code block will be expanded to emit the signal from the object path associated with the interface instance.You can call a signal method from a an interface method, or from an
ObjectServer::with
function. -
out_args
- When returning multiple values from a method, naming the out arguments become important. You can useout_args
to specify their names.In such case, your method must return a tuple containing your out arguments, in the same order as passed to
out_args
.
The struct_return
attribute (from zbus 1.x) is no longer supported. If you want to return a
single structure from a method, declare it to return a tuple containing either a named structure
or a nested tuple.
Note: a <property_name_in_snake_case>_changed
method is generated for each property: this
method emits the “PropertiesChanged” signal for the associated property. The setter (if it
exists) will automatically call this method. For instance, a property setter named set_foo
will be called to set the property “Foo”, and will emit the “PropertiesChanged” signal with the
new value for “Foo”. Other changes to the “Foo” property can be signaled manually with the
generated foo_changed
method. In addition, a <property_name_in_snake_case>_invalidated
method is also generated that much like _changed
method, emits a “PropertyChanged” signal
but does not send over the new value of the property along with it. It is usually best to avoid
using this since it will force all interested peers to fetch the new value and hence result in
excess traffic on the bus.
The method arguments support the following zbus
attributes:
object_server
- This marks the method argument to receive a reference to theObjectServer
this method was called by.connection
- This marks the method argument to receive a reference to theConnection
on which the method call was received.header
- This marks the method argument to receive the message header associated with the D-Bus method call being handled.signal_context
- This marks the method argument to receive aSignalContext
instance, which is needed for emitting signals the easy way.
§Example
use zbus_macros::dbus_interface;
use zbus::{ObjectServer, SignalContext, MessageHeader};
struct Example {
_some_data: String,
}
#[dbus_interface(name = "org.myservice.Example")]
impl Example {
// "Quit" method. A method may throw errors.
async fn quit(
&self,
#[zbus(header)]
hdr: MessageHeader<'_>,
#[zbus(signal_context)]
ctxt: SignalContext<'_>,
#[zbus(object_server)]
_server: &ObjectServer,
) -> zbus::fdo::Result<()> {
let path = hdr.path()?.unwrap();
let msg = format!("You are leaving me on the {} path?", path);
Example::bye(&ctxt, &msg).await?;
// Do some asynchronous tasks before quitting..
Ok(())
}
// "TheAnswer" property (note: the "name" attribute), with its associated getter.
// A `the_answer_changed` method has also been generated to emit the
// "PropertiesChanged" signal for this property.
#[dbus_interface(property, name = "TheAnswer")]
fn answer(&self) -> u32 {
2 * 3 * 7
}
// "IFail" property with its associated getter.
// An `i_fail_changed` method has also been generated to emit the
// "PropertiesChanged" signal for this property.
#[dbus_interface(property)]
fn i_fail(&self) -> zbus::fdo::Result<i32> {
Err(zbus::fdo::Error::UnknownProperty("IFail".into()))
}
// "Bye" signal (note: no implementation body).
#[dbus_interface(signal)]
async fn bye(signal_ctxt: &SignalContext<'_>, message: &str) -> zbus::Result<()>;
#[dbus_interface(out_args("answer", "question"))]
fn meaning_of_life(&self) -> zbus::fdo::Result<(i32, String)> {
Ok((42, String::from("Meaning of life")))
}
}
See also ObjectServer
documentation to learn how to export an interface over a Connection
.