#![deny(missing_docs)]
use std::{
error::Error,
fmt::{self, Display},
path::{Path, PathBuf},
};
#[derive(Debug, Clone, Default)]
pub struct Notification {
app_name: String,
summary: String,
body: String,
icon_path: PathBuf,
timeout: NotificationTimeout,
}
#[derive(Debug, PartialEq, Clone, Default)]
pub enum NotificationTimeout {
#[default]
Default,
Never,
Duration(std::time::Duration),
}
cfg_if::cfg_if! {
if #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))] {
use notify_rust::Timeout;
impl From<NotificationTimeout> for Timeout {
fn from(value: NotificationTimeout) -> Self {
match value {
NotificationTimeout::Default => Timeout::Default,
NotificationTimeout::Never => Timeout::Never,
NotificationTimeout::Duration(dur) => Timeout::Milliseconds(dur.as_millis().try_into().unwrap()),
}
}
}
}
}
impl Notification {
pub fn new() -> Self {
Self::default()
}
pub fn show(&self) -> Result<(), NotificationError> {
self.show_inner()
}
#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
fn show_inner(&self) -> Result<(), NotificationError> {
Err(NotificationError::Unsupported)
}
#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
fn show_inner(&self) -> Result<(), NotificationError> {
let icon_path =
self.icon_path
.as_os_str()
.to_str()
.ok_or(NotificationError::FailedToShow(
"failed to convert icon path into str".into(),
))?;
notify_rust::Notification::new()
.appname(&self.app_name)
.summary(&self.summary)
.body(&self.body)
.icon(icon_path)
.timeout(self.timeout.clone())
.show()
.map_err(|e| NotificationError::FailedToShow(e.into()))?;
Ok(())
}
pub fn app_name(&mut self, value: impl ToString) -> &mut Self {
self.app_name = value.to_string();
self
}
pub fn summary(&mut self, value: impl ToString) -> &mut Self {
self.summary = value.to_string();
self
}
pub fn body(&mut self, value: impl ToString) -> &mut Self {
self.body = value.to_string();
self
}
pub fn icon_path(&mut self, value: impl AsRef<Path>) -> &mut Self {
self.icon_path = value.as_ref().to_path_buf();
self
}
pub fn timeout(&mut self, value: NotificationTimeout) -> &mut Self {
self.timeout = value;
self
}
}
#[test]
#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
fn test_notification() {
Notification::new()
.app_name("dioxus test".to_string())
.summary("hi, this is dioxus test".to_string())
.body("lorem ipsum??".to_string())
.show()
.unwrap();
}
#[derive(Debug)]
pub enum NotificationError {
Unsupported,
FailedToShow(Box<dyn Error>),
}
impl Error for NotificationError {}
impl Display for NotificationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Unsupported => write!(f, "notification is not supported on this platform"),
Self::FailedToShow(err) => write!(f, "failed to show notification: {err}"),
}
}
}