use super::{DESTINATION, PATH};
use crate::{
helpers::{call_method, receive_signal},
Error,
};
use serde::{self, Deserialize, Serialize, Serializer};
use strum_macros::{AsRefStr, EnumString, IntoStaticStr, ToString};
use zvariant::{OwnedValue, Signature};
use zvariant_derive::{DeserializeDict, SerializeDict, Type, TypeDict};
#[derive(
Debug, Clone, Deserialize, AsRefStr, EnumString, IntoStaticStr, ToString, PartialEq, Eq,
)]
#[strum(serialize_all = "lowercase")]
pub enum Priority {
Low,
Normal,
High,
Urgent,
}
impl zvariant::Type for Priority {
fn signature() -> Signature<'static> {
String::signature()
}
}
impl Serialize for Priority {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
String::serialize(&self.to_string(), serializer)
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug)]
pub struct Notification {
title: String,
body: Option<String>,
icon: Option<OwnedValue>,
priority: Option<Priority>,
#[zvariant(rename = "default-action")]
default_action: Option<String>,
#[zvariant(rename = "default-action-target")]
default_action_target: Option<OwnedValue>,
buttons: Option<Vec<Button>>,
}
impl Notification {
pub fn new(title: &str) -> Self {
Self {
title: title.to_string(),
body: None,
priority: None,
icon: None,
default_action: None,
default_action_target: None,
buttons: None,
}
}
pub fn body(mut self, body: &str) -> Self {
self.body = Some(body.to_string());
self
}
pub fn icon(mut self, icon: OwnedValue) -> Self {
self.icon = Some(icon);
self
}
pub fn priority(mut self, priority: Priority) -> Self {
self.priority = Some(priority);
self
}
pub fn default_action(mut self, default_action: &str) -> Self {
self.default_action = Some(default_action.to_string());
self
}
pub fn default_action_target(mut self, default_action_target: OwnedValue) -> Self {
self.default_action_target = Some(default_action_target);
self
}
pub fn button(mut self, button: Button) -> Self {
match self.buttons {
Some(ref mut buttons) => buttons.push(button),
None => {
self.buttons.replace(vec![button]);
}
};
self
}
}
#[derive(SerializeDict, DeserializeDict, TypeDict, Debug)]
pub struct Button {
label: String,
action: String,
target: Option<OwnedValue>,
}
impl Button {
pub fn new(label: &str, action: &str) -> Self {
Self {
label: label.to_string(),
action: action.to_string(),
target: None,
}
}
pub fn target(mut self, target: OwnedValue) -> Self {
self.target = Some(target);
self
}
}
#[derive(Debug, Serialize, Deserialize, Type)]
pub struct Action(String, String, Vec<OwnedValue>);
impl Action {
pub fn id(&self) -> &str {
&self.0
}
pub fn name(&self) -> &str {
&self.1
}
pub fn parameter(&self) -> &Vec<OwnedValue> {
&self.2
}
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.Notification")]
pub struct NotificationProxy<'a>(zbus::azync::Proxy<'a>);
impl<'a> NotificationProxy<'a> {
pub async fn new(connection: &zbus::azync::Connection) -> Result<NotificationProxy<'a>, Error> {
let proxy = zbus::ProxyBuilder::new_bare(connection)
.interface("org.freedesktop.portal.Notification")
.path(PATH)?
.destination(DESTINATION)
.build_async()
.await?;
Ok(Self(proxy))
}
pub fn inner(&self) -> &zbus::azync::Proxy<'_> {
&self.0
}
#[doc(alias = "ActionInvoked")]
pub async fn receive_action_invoked(&self) -> Result<Action, Error> {
receive_signal(&self.0, "ActionInvoked").await
}
#[doc(alias = "AddNotification")]
pub async fn add_notification(
&self,
id: &str,
notification: Notification,
) -> Result<(), Error> {
call_method(&self.0, "AddNotification", &(id, notification)).await
}
#[doc(alias = "RemoveNotification")]
pub async fn remove_notification(&self, id: &str) -> Result<(), Error> {
call_method(&self.0, "RemoveNotification", &(id)).await
}
}