#dbus #api-bindings #xml #introspection #generate #interface #data

bin+lib dbus-codegen

用于从 XML 检查数据生成 Rust 代码的二进制包

12 个版本 (7 个破坏性更改)

0.12.0 2024 年 5 月 29 日
0.11.0 2024 年 2 月 19 日
0.10.0 2021 年 10 月 13 日
0.9.1 2021 年 1 月 5 日
0.2.0 2017 年 11 月 11 日

#206Unix API

Download history 2019/week @ 2024-05-03 1828/week @ 2024-05-10 1970/week @ 2024-05-17 2068/week @ 2024-05-24 2572/week @ 2024-05-31 1895/week @ 2024-06-07 1548/week @ 2024-06-14 1896/week @ 2024-06-21 1521/week @ 2024-06-28 1849/week @ 2024-07-05 1947/week @ 2024-07-12 2102/week @ 2024-07-19 2371/week @ 2024-07-26 1686/week @ 2024-08-02 2211/week @ 2024-08-09 1530/week @ 2024-08-16

每月下载量 8,312
用于 13 包(5 个直接使用)

Apache-2.0/MIT

530KB
10K SLoC

dbus-codegen-rust

此程序接受 D-Bus XML 检查数据,并生成调用和实现检查数据中接口的 Rust 代码。

示例

从这样的 D-Bus 接口

<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>

您可以选择生成以下三者之一

  • 客户端代码(用于调用接口)
  • 使用 dbus-crossroads 实现接口的服务器端代码
  • 使用 dbus-tree 实现接口的服务器端代码

客户端和服务器端通用

  • 一个用于调用/实现接口方法的 trait,如下所示
pub trait OrgExampleTest {
    fn foo(&self, bar: i32) -> Result<String, dbus::Error>;
}
pub trait OrgExampleTest {
    fn foo(&self, bar: i32) -> Result<String, dbus::MethodErr>;
}

对于属性,将生成 get_xxset_xx 方法。目前没有 get_all 方法。

  • 每个信号一个 struct,如下所示
#[derive(Debug, Default)]
pub struct OrgExampleTestLaundry {
    pub eaten: bool,
}

impl dbus::SignalArgs for OrgExampleTestLaundry { /* code here */ }

客户端

  • 将为 blocking::Proxynonblock::Proxyffidisp::ConnPath 实现 trait,这使得客户端调用方法变得容易,如下所示
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);
})

服务器端 - dbus-crossroads

  • 将生成一个注册 IfaceToken 的方法,如下所示
let token = register_org_example_test(&mut myCrossroads);
myCrossroads.insert("/", &[token], myData);

其中 myData 必须是实现了 OrgExampleTest 的类型。

服务器端 - dbus-tree

  • 将生成一个方法,您可以通过调用它来获取 tree::Interface,如下所示
myInterface = orgexampletest_server(&myFactory, ());

然后将此接口添加到 tree::ObjectPath 中,如 主页 所示。

此外,您还需要实现接口的方法,如下所示

impl OrgExampleTest for MyStruct {
    type Err = tree::MethodErr;
    fn foo(&self, bar: i32) -> Result<String, Self::Err> {
        /* Your code here */
    }
}

我一直在尝试不同的方法,以使生成的服务器函数能够到达实现的结构体,这由命令行参数 methodaccess 控制。

  1. 如果 methodaccessMethodInfo,那么您需要实现 MethodInfo 结构体的接口,如下所示
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 */
    }
}
  1. 如果 methodaccessRefClosure,那么您需要提供一个返回实现结构体引用的闭包。如果结构体存储在树中(这意味着实现 tree::DataType),这是一个很好的选项。
myInterface = orgexampletest_server(&myFactory, (), |m| m.path.get_data());
  1. 如果 methodaccessAsRefClosure,那么您需要提供一个返回可以引用实现结构体的对象的闭包。在方法调用后,该对象会被丢弃。这很好地与 Arc/Rc 一起工作,如下所示
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());

还有一个 methodtype 参数,用于控制服务器函数是否与 MTFnMTFnMutMTSync 树一起正常工作,或者三者都工作(称为 Generic)。或者根本不生成服务器函数(None)。

  • 要发出信号,您可以调用 SignalArgs::to_emit_messageConnPath::emit 以获取可以发送到连接的消息。

用法

此代码既可以作为库使用,也可以作为二进制可执行文件。

二进制可执行文件

一旦安装了 dbus-codegen-rust(cargo install dbus-codegen),请使用以下命令导入您的 XML 文件

dbus-codegen-rust < mydefinition.xml

这将打印生成的 Rust 代码到 stdout,因此如果您想将其管道传输到另一个文件,可以这样做

dbus-codegen-rust < mydefinition.xml > mod.rs

Dbus-codegen-rust 还可以为您获取 xml 定义。以下是一个为 PolicyKit 生成客户端定义的示例

dbus-codegen-rust -s -d org.freedesktop.PolicyKit1 -p "/org/freedesktop/PolicyKit1/Authority" > policykit.rs

Dbus-codegen-rust 默认生成客户端定义。使用 --crossroads 开关生成 dbus-crossroads 服务器定义,并使用 --methodtype 生成 dbus-tree 定义。

要查看可用选项

dbus-codegen-rust --help

库使用

let opts = Default::default();
let code = dbus_codegen::generate(xml_str, &opts)?;

有关可用选项的说明,请参阅文档

功能

dbus 功能默认启用。如果您将其关闭(通过 cargo 的 --no-default-features 参数),则此程序(或库)不再绑定到 D-Bus C 开发头文件,这意味着您不需要安装这些文件。这也意味着您在运行二进制文件时无法从其他程序获取 xml 定义。

依赖项

~6MB
~127K SLoC