Generate dbus bindings from xml descriptions

This commit is contained in:
Artemis Tosini 2023-12-14 21:08:33 +00:00
parent b22089d58b
commit 92a611581f
Signed by: artemist
GPG key ID: EE5227935FE3FF18
7 changed files with 115 additions and 3 deletions

17
Cargo.lock generated
View file

@ -213,6 +213,16 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "dbus-codegen"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76dc35ce83e4e9fa089b4fabe66c757b27bd504dc2179c97a01b36d3e874fb0"
dependencies = [
"clap",
"xml-rs",
]
[[package]] [[package]]
name = "dbus-tokio" name = "dbus-tokio"
version = "0.7.6" version = "0.7.6"
@ -993,6 +1003,7 @@ dependencies = [
"chrono", "chrono",
"chrono-tz", "chrono-tz",
"dbus", "dbus",
"dbus-codegen",
"dbus-tokio", "dbus-tokio",
"eyre", "eyre",
"local-ip-address", "local-ip-address",
@ -1742,3 +1753,9 @@ dependencies = [
"cfg-if", "cfg-if",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "xml-rs"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"

View file

@ -27,6 +27,9 @@ tokio-stream = { version = "0.1", features = ["time"]}
toml = "0.8" toml = "0.8"
uuid = { version = "1.4", features = [ "v4" ] } uuid = { version = "1.4", features = [ "v4" ] }
[build-dependencies]
dbus-codegen = { version = "0.10", default-features = false }
[profile.release] [profile.release]
incremental = false incremental = false
codegen-units = 1 codegen-units = 1

81
build.rs Normal file
View file

@ -0,0 +1,81 @@
use std::collections::HashSet;
use std::env;
use std::fs;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use dbus_codegen::ConnectionType;
use dbus_codegen::GenOpts;
fn main() {
println!("cargo:rerun-if-env-changed=DBUS_XML_PATH");
println!("cargo:rerun-if-changed=build.rs");
let required_files = HashSet::from(["org.freedesktop.hostname1.xml"]);
let required_interfaces = required_files
.iter()
.map(|name| name.strip_suffix(".xml").unwrap().to_string())
.collect();
let opts = GenOpts {
connectiontype: ConnectionType::Nonblock,
methodtype: None,
interfaces: Some(required_interfaces),
..Default::default()
};
let out_dir_str = env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir_str);
let mut generated_file = fs::File::create(out_dir.join("generated.rs")).unwrap();
let dbus_paths_raw =
env::var("DBUS_XML_PATH").unwrap_or("/usr/share/dbus-1/interfaces".to_string());
dbus_paths_raw
.split(':')
.map(fs::read_dir)
.flat_map(Result::unwrap)
.map(Result::unwrap)
.filter(|file| required_files.contains(file.file_name().to_str().unwrap()))
.for_each(|in_file| {
println!(
"cargo:rerun-if-changed={}",
in_file.path().to_str().unwrap()
);
let mut xml = String::new();
fs::File::open(in_file.path())
.unwrap()
.read_to_string(&mut xml)
.unwrap();
let code = dbus_codegen::generate(&xml, &opts).unwrap();
let module_name = in_file
.file_name()
.into_string()
.unwrap()
.strip_suffix(".xml")
.unwrap()
.replace('.', "_");
let out_path = out_dir.join(module_name.clone() + ".rs");
fs::File::create(out_path)
.unwrap()
.write_all(code.as_bytes())
.unwrap();
generated_file
.write_all(
format!(
r#"mod {module_name} {{
include!(concat!(env!("OUT_DIR"), "/{module_name}.rs"));
}}
pub use {module_name}::*;
"#
)
.as_bytes(),
)
.unwrap();
})
}

View file

@ -9,7 +9,11 @@
outputs = { self, nixpkgs, utils }: outputs = { self, nixpkgs, utils }:
let supportedSystems = [ "x86_64-linux" "aarch64-linux" ]; let supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
in (utils.lib.eachSystem supportedSystems (system: in (utils.lib.eachSystem supportedSystems (system:
let pkgs = import nixpkgs { inherit system; }; let
pkgs = import nixpkgs { inherit system; };
inherit (pkgs) lib;
dbusPaths = lib.makeSearchPathOutput "out" "share/dbus-1/interfaces"
(with pkgs; [ systemd ]);
in rec { in rec {
packages.rustybar = with pkgs; packages.rustybar = with pkgs;
rustPlatform.buildRustPackage { rustPlatform.buildRustPackage {
@ -21,6 +25,8 @@
nativeBuildInputs = [ pkg-config ]; nativeBuildInputs = [ pkg-config ];
buildInputs = [ dbus ]; buildInputs = [ dbus ];
DBUS_XML_PATH = dbusPaths;
meta = with lib; { meta = with lib; {
homepage = "https://github.com/mildlyfunctionalgays/rustybar"; homepage = "https://github.com/mildlyfunctionalgays/rustybar";
description = "swaybar/i3bar command in Rust"; description = "swaybar/i3bar command in Rust";
@ -45,6 +51,7 @@
rustPackages.rustfmt rustPackages.rustfmt
rustPackages.clippy rustPackages.clippy
]; ];
DBUS_XML_PATH = dbusPaths;
RUST_SRC_PATH = RUST_SRC_PATH =
"${rustPackages.rustPlatform.rustLibSrc}/lib/rustlib"; "${rustPackages.rustPlatform.rustLibSrc}/lib/rustlib";
}; };

3
src/generated.rs Normal file
View file

@ -0,0 +1,3 @@
#![allow(clippy::needless_borrow)]
include!(concat!(env!("OUT_DIR"), "/generated.rs"));

View file

@ -1,4 +1,5 @@
mod config; mod config;
mod generated;
mod output; mod output;
mod tile; mod tile;
mod tiles; mod tiles;

View file

@ -1,7 +1,7 @@
use crate::config::HostnameConfig; use crate::config::HostnameConfig;
use crate::generated::OrgFreedesktopHostname1;
use crate::output::OutputChannel; use crate::output::OutputChannel;
use crate::tile::Block; use crate::tile::Block;
use dbus::nonblock::stdintf::org_freedesktop_dbus::Properties;
use dbus::nonblock::{Proxy, SyncConnection}; use dbus::nonblock::{Proxy, SyncConnection};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
@ -19,7 +19,7 @@ pub async fn hostname(
); );
let mut interval = tokio::time::interval(config.update); let mut interval = tokio::time::interval(config.update);
loop { loop {
let reply = proxy.get("org.freedesktop.hostname1", "Hostname"); let reply = proxy.hostname();
let hostname: String = reply.await?; let hostname: String = reply.await?;
output output
.send(Block { .send(Block {