This repository is home to zbus-lockstep
and zbus-lockstep-macros
.
These crates help keep type definitions in lockstep with DBus XML descriptions, using zbus-xml
.
These offer means to match your type's signature - <T as zvariant::Type>::signature()
- with a corresponding signature retrieved from a DBus XML file.
This way zbus-lockstep
and zbus-lockstep-macros
prevent definitions from drifting apart.
In the context of IPC over DBus
, especially where there are multiple implementations of servers and/or clients communicating, it is necessary for each implementation to send what others expect and that expectations are in accordance with what is sent over the bus.
The XML
protocol-descriptions may act as a shared frame of reference or "single source of all truth" for all implementers.
Having a single point of reference helps all implementers meet expectations on protocol conformance.
Keeping the types you send over DBus
in lockstep with currently valid protocol-descriptions will reduce chances of miscommunication or failure to communicate.
Consider the followwing XML description,
an interface with a single, simple signal in the Cache.xml
file:
<node>
<interface name="org.example.Node">
<signal name="RemoveNode">
<arg name="nodeRemoved" type="(so)"/>
</signal>
</interface>
</node>
The type in our implementation might look like this:
#[derive(Type)]
struct Node {
name: String,
path: OwnedObjectPath,
}
The derive macro in this example implements the zvariant::Type
.
This means we can now call <Node as Type::signature()
, which will return a zvariant::Signature
of the type.
The test below shows how zbus-lockstep
may be used to assure our implementation is indeed in lockstep with the protocol descriptions.
use zbus_lockstep;
#[test]
fn test_get_signature_of_cache_remove_accessible() {
let xml = PathBuf::from("xml/Node.xml");
let iface = "org.example.Node";
let member = "RemoveNode";
let signature = get_signal_body_type(xml, iface, member, None).unwrap();
assert_eq!(signature, Node::signature());
}
This common case can also be handled even more succinctly by zbus-lockstap-macros::validate
, shown below:
use zbus_lockstep_macros::validate;
#[validate]
#[derive(Type)]
struct Node {
name: String,
path: OwnedObjectPath,
}
Which does essentially the same as the previous example.
See either crate and their docs for more details on usage and options.
When using XML descriptions as point of reference, you should ensure that the descriptions in use are always the most recent available.
Automated synchronizing would be preferred.
zbus-lockstep
started out as a fork of Tait Hoyem's zbus-xml-match.
MIT