#[cfg(feature = "dbus")]
use dbus::ffidisp::Connection as DbusConnection;
use crate::{error::*, notification::Notification};
use std::ops::{Deref, DerefMut};
#[cfg(feature = "dbus")]
mod dbus_rs;
#[cfg(feature = "zbus")]
mod zbus_rs;
#[cfg(not(feature = "debug_namespace"))]
pub static NOTIFICATION_NAMESPACE: &str = "org.freedesktop.Notifications";
#[cfg(not(feature = "debug_namespace"))]
pub static NOTIFICATION_OBJECTPATH: &str = "/org/freedesktop/Notifications";
#[cfg(feature = "debug_namespace")]
pub static NOTIFICATION_NAMESPACE: &str = "de.hoodie.Notifications";
#[cfg(feature = "debug_namespace")]
pub static NOTIFICATION_OBJECTPATH: &str = "/de/hoodie/Notifications";
#[derive(Debug)]
enum NotificationHandleInner {
#[cfg(feature = "dbus")]
Dbus(dbus_rs::DbusNotificationHandle),
#[cfg(feature = "zbus")]
Zbus(zbus_rs::ZbusNotificationHandle),
}
#[derive(Debug)]
pub struct NotificationHandle {
inner: NotificationHandleInner,
}
#[allow(dead_code)]
impl NotificationHandle {
#[cfg(feature = "dbus")]
pub(crate) fn for_dbus(id: u32, connection: DbusConnection, notification: Notification) -> NotificationHandle {
NotificationHandle {
inner: dbus_rs::DbusNotificationHandle::new(id, connection, notification).into(),
}
}
#[cfg(feature = "zbus")]
pub(crate) fn for_zbus(id: u32, connection: zbus::Connection, notification: Notification) -> NotificationHandle {
NotificationHandle {
inner: zbus_rs::ZbusNotificationHandle::new(id, connection, notification).into(),
}
}
pub fn wait_for_action<F>(self, invocation_closure: F)
where
F: FnOnce(&str),
{
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(inner) => inner.wait_for_action(invocation_closure),
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(inner) => inner.wait_for_action(invocation_closure),
}
}
pub fn close(self) {
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(inner) => inner.close(),
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(inner) => inner.close(),
}
}
pub fn on_close<F>(self, closure: F)
where
F: FnOnce(),
{
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(inner) => inner.wait_for_action(|action| {
if action == "__closed" {
closure();
}
}),
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(inner) => inner.wait_for_action(|action| {
if action == "__closed" {
closure();
}
}),
}
}
pub fn update(&mut self) {
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(ref mut inner) => inner.update(),
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(ref mut inner) => inner.update(),
}
}
pub fn id(&self) -> u32 {
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(ref inner) => inner.id,
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(ref inner) => inner.id,
}
}
}
impl Deref for NotificationHandle {
type Target = Notification;
fn deref(&self) -> &Notification {
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(ref inner) => &inner.notification,
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(ref inner) => &inner.notification,
}
}
}
impl DerefMut for NotificationHandle {
fn deref_mut(&mut self) -> &mut Notification {
match self.inner {
#[cfg(feature = "dbus")]
NotificationHandleInner::Dbus(ref mut inner) => &mut inner.notification,
#[cfg(feature = "zbus")]
NotificationHandleInner::Zbus(ref mut inner) => &mut inner.notification,
}
}
}
#[cfg(feature = "dbus")]
impl From<dbus_rs::DbusNotificationHandle> for NotificationHandleInner {
fn from(handle: dbus_rs::DbusNotificationHandle) -> NotificationHandleInner {
NotificationHandleInner::Dbus(handle)
}
}
#[cfg(feature = "zbus")]
impl From<zbus_rs::ZbusNotificationHandle> for NotificationHandleInner {
fn from(handle: zbus_rs::ZbusNotificationHandle) -> NotificationHandleInner {
NotificationHandleInner::Zbus(handle)
}
}
#[cfg(feature = "dbus")]
impl From<dbus_rs::DbusNotificationHandle> for NotificationHandle {
fn from(handle: dbus_rs::DbusNotificationHandle) -> NotificationHandle {
NotificationHandle { inner: handle.into() }
}
}
#[cfg(feature = "zbus")]
impl From<zbus_rs::ZbusNotificationHandle> for NotificationHandle {
fn from(handle: zbus_rs::ZbusNotificationHandle) -> NotificationHandle {
NotificationHandle { inner: handle.into() }
}
}
#[cfg(all(not(any(feature = "dbus", feature="zbus")), unix, not(target_os = "macos")))]
compile_error!("you have to build with eiter zbus or dbus turned on");
#[derive(Copy, Clone, Debug)]
pub enum DbusStack {
Dbus,
Zbus,
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
const ZBUS_SWITCH_VAR: &str = "ZBUS_NOTIFICATION";
#[cfg(all(feature = "zbus", not(feature = "dbus")))]
pub(crate) fn show_notification(notification: &Notification) -> Result<NotificationHandle> {
zbus_rs::connect_and_send_notification(notification).map(Into::into)
}
#[cfg(all(feature = "dbus", not(feature = "zbus")))]
pub(crate) fn show_notification(notification: &Notification) -> Result<NotificationHandle> {
dbus_rs::connect_and_send_notification(notification).map(Into::into)
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
pub(crate) fn show_notification(notification: &Notification) -> Result<NotificationHandle> {
if std::env::var(ZBUS_SWITCH_VAR).is_ok() {
zbus_rs::connect_and_send_notification(notification).map(Into::into)
} else {
dbus_rs::connect_and_send_notification(notification).map(Into::into)
}
}
#[cfg(all(feature = "zbus", not(feature = "dbus")))]
pub fn dbus_stack() -> Option<DbusStack> {
Some(DbusStack::Zbus)
}
#[cfg(all(feature = "dbus", not(feature = "zbus")))]
pub fn dbus_stack() -> Option<DbusStack> {
Some(DbusStack::Dbus)
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
pub fn dbus_stack() -> Option<DbusStack> {
Some(if std::env::var(ZBUS_SWITCH_VAR).is_ok() {
DbusStack::Zbus
} else {
DbusStack::Dbus
})
}
#[cfg(all(not(feature = "dbus"), not(feature = "zbus")))]
pub fn dbus_stack() -> Option<DbusStack> {
None
}
#[cfg(all(feature = "zbus", not(feature = "dbus")))]
pub fn get_capabilities() -> Result<Vec<String>> {
zbus_rs::get_capabilities()
}
#[cfg(all(feature = "dbus", not(feature = "zbus")))]
pub fn get_capabilities() -> Result<Vec<String>> {
dbus_rs::get_capabilities()
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
pub fn get_capabilities() -> Result<Vec<String>> {
if std::env::var(ZBUS_SWITCH_VAR).is_ok() {
zbus_rs::get_capabilities()
} else {
dbus_rs::get_capabilities()
}
}
#[cfg(all(feature = "zbus", not(feature = "dbus")))]
pub fn get_server_information() -> Result<ServerInformation> {
zbus_rs::get_server_information()
}
#[cfg(all(feature = "dbus", not(feature = "zbus")))]
pub fn get_server_information() -> Result<ServerInformation> {
dbus_rs::get_server_information()
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
pub fn get_server_information() -> Result<ServerInformation> {
if std::env::var(ZBUS_SWITCH_VAR).is_ok() {
zbus_rs::get_server_information()
} else {
dbus_rs::get_server_information()
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "zbus", derive(zvariant_derive::Type))]
pub struct ServerInformation {
pub name: String,
pub vendor: String,
pub version: String,
pub spec_version: String,
}
#[cfg(all(feature = "server", unix, not(target_os = "macos")))]
#[doc(hidden)]
pub fn stop_server() {
#[cfg(feature = "dbus")]
dbus_rs::stop_server()
}
#[cfg(all(feature = "zbus", not(feature = "dbus")))]
pub fn handle_action<F>(id: u32, func: F)
where
F: FnOnce(&str),
{
zbus_rs::handle_action(id, func)
}
#[cfg(all(feature = "dbus", not(feature = "zbus")))]
pub fn handle_action<F>(id: u32, func: F)
where
F: FnOnce(&str),
{
dbus_rs::handle_action(id, func)
}
#[cfg(all(feature = "dbus", feature = "zbus"))]
pub fn handle_action<F>(id: u32, func: F)
where
F: FnOnce(&str),
{
if std::env::var(ZBUS_SWITCH_VAR).is_ok() {
zbus_rs::handle_action(id, func)
} else {
dbus_rs::handle_action(id, func)
}
}