aboutsummaryrefslogtreecommitdiff
path: root/gd/rust/linux/dbus_projection/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gd/rust/linux/dbus_projection/src/lib.rs')
-rw-r--r--gd/rust/linux/dbus_projection/src/lib.rs102
1 files changed, 0 insertions, 102 deletions
diff --git a/gd/rust/linux/dbus_projection/src/lib.rs b/gd/rust/linux/dbus_projection/src/lib.rs
deleted file mode 100644
index 7d948a730..000000000
--- a/gd/rust/linux/dbus_projection/src/lib.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//! This crate provides tools to automatically project generic API to D-Bus RPC.
-//!
-//! For D-Bus projection to work automatically, the API needs to follow certain restrictions.
-
-use dbus::channel::MatchingReceiver;
-use dbus::message::MatchRule;
-use dbus::nonblock::SyncConnection;
-use dbus::strings::BusName;
-
-use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
-
-/// A D-Bus "NameOwnerChanged" handler that continuously monitors client disconnects.
-pub struct DisconnectWatcher {
- callbacks: Arc<Mutex<HashMap<BusName<'static>, Vec<Box<dyn Fn() + Send>>>>>,
-}
-
-impl DisconnectWatcher {
- /// Creates a new DisconnectWatcher with empty callbacks.
- pub fn new() -> DisconnectWatcher {
- DisconnectWatcher { callbacks: Arc::new(Mutex::new(HashMap::new())) }
- }
-}
-
-impl DisconnectWatcher {
- /// Adds a client address to be monitored for disconnect events.
- pub fn add(&mut self, address: BusName<'static>, callback: Box<dyn Fn() + Send>) {
- if !self.callbacks.lock().unwrap().contains_key(&address) {
- self.callbacks.lock().unwrap().insert(address.clone(), vec![]);
- }
-
- (*self.callbacks.lock().unwrap().get_mut(&address).unwrap()).push(callback);
- }
-
- /// Sets up the D-Bus handler that monitors client disconnects.
- pub async fn setup_watch(&mut self, conn: Arc<SyncConnection>) {
- let mr = MatchRule::new_signal("org.freedesktop.DBus", "NameOwnerChanged");
-
- conn.add_match_no_cb(&mr.match_str()).await.unwrap();
- let callbacks_map = self.callbacks.clone();
- conn.start_receive(
- mr,
- Box::new(move |msg, _conn| {
- // The args are "address", "old address", "new address".
- // https://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-name-owner-changed
- let (addr, old, new) = msg.get3::<String, String, String>();
-
- if addr.is_none() || old.is_none() || new.is_none() {
- return true;
- }
-
- if old.unwrap().eq("") || !new.unwrap().eq("") {
- return true;
- }
-
- // If old address exists but new address is empty, that means that client is
- // disconnected. So call the registered callbacks to be notified of this client
- // disconnect.
- let addr = BusName::new(addr.unwrap()).unwrap().into_static();
- if !callbacks_map.lock().unwrap().contains_key(&addr) {
- return true;
- }
-
- for callback in &callbacks_map.lock().unwrap()[&addr] {
- callback();
- }
-
- callbacks_map.lock().unwrap().remove(&addr);
-
- true
- }),
- );
- }
-}
-
-#[macro_export]
-macro_rules! impl_dbus_arg_enum {
- ($enum_type:ty) => {
- impl DBusArg for $enum_type {
- type DBusType = i32;
- fn from_dbus(
- data: i32,
- _conn: Arc<SyncConnection>,
- _remote: BusName<'static>,
- _disconnect_watcher: Arc<Mutex<dbus_projection::DisconnectWatcher>>,
- ) -> Result<$enum_type, Box<dyn Error>> {
- match <$enum_type>::from_i32(data) {
- Some(x) => Ok(x),
- None => Err(Box::new(DBusArgError::new(String::from(format!(
- "error converting {} to {}",
- data,
- stringify!($enum_type)
- ))))),
- }
- }
-
- fn to_dbus(data: $enum_type) -> Result<i32, Box<dyn Error>> {
- return Ok(data.to_i32().unwrap());
- }
- }
- };
-}