| Crates.io | dbus-codegen |
| lib.rs | dbus-codegen |
| version | 0.12.0 |
| created_at | 2017-11-11 03:51:19.225907+00 |
| updated_at | 2024-05-29 17:48:20.806933+00 |
| description | Binary crate to generate Rust code from XML introspection data |
| homepage | |
| repository | https://github.com/diwic/dbus-rs |
| max_upload_size | |
| id | 38957 |
| size | 94,381 |
This program takes D-Bus XML Introspection data and generates Rust code for calling and implementing the interfaces in the introspection data.
From a D-Bus interface like this:
<node>
<interface name="org.example.test">
<method name="Foo">
<arg type="i" name="bar" direction="in"/>
<arg type="s" name="baz" direction="out"/>
</method>
<signal name="Laundry">
<arg type="b" name="eaten"/>
</signal>
</interface>
</node>
You can choose to generate one of three things:
pub trait OrgExampleTest {
fn foo(&self, bar: i32) -> Result<String, dbus::Error>;
}
pub trait OrgExampleTest {
fn foo(&self, bar: i32) -> Result<String, dbus::MethodErr>;
}
For properties, get_xx and set_xx methods will be generated. There is currently no get_all method.
#[derive(Debug, Default)]
pub struct OrgExampleTestLaundry {
pub eaten: bool,
}
impl dbus::SignalArgs for OrgExampleTestLaundry { /* code here */ }
blocking::Proxy, nonblock::Proxy or ffidisp::ConnPath,
which makes methods easy to call for a client, like this:use OrgExampleTest;
let myString = myProxy.foo(myInteger)?;
use dbus::SignalArgs;
myConnection.add_match(OrgExampleTestLaundry::match_rule(None, None).into_static(), |laundrySignal| {
println!("Laundry was eaten: {:?}", laundrySignal.eaten);
})
IfaceToken, like this:let token = register_org_example_test(&mut myCrossroads);
myCrossroads.insert("/", &[token], myData);
Where myData must be of a type that implements OrgExampleTest.
tree::Interface, like this:myInterface = orgexampletest_server(&myFactory, ());
This interface can then be added to a tree::ObjectPath, as shown in the main page.
In addition, you also need to implement the interface's methods, like this:
impl OrgExampleTest for MyStruct {
type Err = tree::MethodErr;
fn foo(&self, bar: i32) -> Result<String, Self::Err> {
/* Your code here */
}
}
I've been experimenting with different ways of how to make the generated server function reach the implementing struct,
this is controlled by the command line parameter methodaccess.
methodaccess is MethodInfo, then you need to implement the interface for the MethodInfo struct, like this:impl<M: tree::MethodType<D>, D> OrgExampleTest for tree::MethodInfo<M, D> {
type Err = tree::MethodErr;
fn foo(&self, bar: i32) -> Result<String, Self::Err> {
/* Your code here */
}
}
methodaccess is RefClosure, then you need to supply a closure that returns a reference to the implementing struct.
This is a good option if the struct is stored in tree (this means implementing tree::DataType).myInterface = orgexampletest_server(&myFactory, (), |m| m.path.get_data());
methodaccess is AsRefClosure, then you need to supply a closure that returns an object which can reference to the implementing struct.
The object is dropped after the method is called. This works well with Arc/Rc, like this:impl AsRef<dyn OrgExampleTest + 'static> for Rc<MyStruct> {
fn as_ref(&self) -> &(dyn OrgExampleTest + 'static) { &**self }
}
let myRc = Rc::new(myStruct);
myInterface = orgexampletest_server(&myFactory, (), move |_| myRc.clone());
There is also a methodtype parameter that controls whether the server function will work well with MTFn, MTFnMut or MTSync trees,
or all three (called Generic). Or not generate a server function at all (None).
SignalArgs::to_emit_message or ConnPath::emit to get a message which can be sent over the connection.This code can be used both as a library and as a binary executable.
Once you have installed dbus-codegen-rust (cargo install dbus-codegen), use the following command to import your XML:
dbus-codegen-rust < mydefinition.xml
This will print the generated Rust code to stdout, so you can pipe it into another file if you want:
dbus-codegen-rust < mydefinition.xml > mod.rs
Dbus-codegen-rust can also fetch the xml definition for you. Here's an example that generates client definitions for PolicyKit:
dbus-codegen-rust -s -d org.freedesktop.PolicyKit1 -p "/org/freedesktop/PolicyKit1/Authority" > policykit.rs
Dbus-codegen-rust defaults to generating client definitions. Use the --crossroads switch to
generate dbus-crossroads server definitions and --methodtype to generate dbus-tree definitions.
To see available options:
dbus-codegen-rust --help
let opts = Default::default();
let code = dbus_codegen::generate(xml_str, &opts)?;
See documentation for what options are available.
The dbus feature is enabled by default. If you turn it off (with the --no-default-features argument to cargo),
this program (or library) no longer binds to the D-Bus C development headers, meaning you don't need these to be installed.
This also means you can no longer fetch the xml definition from other programs when you run the binary.