#[cfg(any(doc, feature = "callbacks"))]
pub mod callbacks;
mod options;
pub mod remove_handle;
use std::{
collections::HashMap,
io,
process::{Command, Output},
};
use remove_handle::RemoveHandle;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct TermuxNotification {
args: HashMap<&'static str, Option<String>>,
}
impl TermuxNotification {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn id(&mut self, id: impl Into<String>) -> &mut Self {
self.args.insert(options::ID, Some(id.into()));
self
}
pub fn title(&mut self, title: impl Into<String>) -> &mut Self {
self.args.insert(options::TITLE, Some(title.into()));
self
}
pub fn content(&mut self, content: impl Into<String>) -> &mut Self {
self.args.insert(options::CONTENT, Some(content.into()));
self
}
pub fn icon(&mut self, icon: impl Into<String>) -> &mut Self {
self.args.insert(options::ICON, Some(icon.into()));
self
}
pub fn alert_once(&mut self, alert_once: bool) -> &mut Self {
let k = options::ALERT_ONCE;
if alert_once {
self.args.insert(k, None);
} else {
self.args.remove(k);
}
self
}
pub fn ongoing(&mut self, ongoing: bool) -> &mut Self {
let k = options::ONGOING;
if ongoing {
self.args.insert(k, None);
} else {
self.args.remove(k);
}
self
}
pub fn action(&mut self, action: impl Into<String>) -> &mut Self {
self.args.insert(options::ACTION, Some(action.into()));
self
}
pub fn on_delete(
&mut self,
on_delete: impl Into<String>,
) -> &mut Self {
self.args.insert(options::ON_DELETE, Some(on_delete.into()));
self
}
pub fn button1(
&mut self,
label: impl Into<String>,
action: impl Into<String>,
) -> &mut Self {
self.args.insert(options::BUTTON1, Some(label.into()));
self
.args
.insert(options::BUTTON1_ACTION, Some(action.into()));
self
}
pub fn button2(
&mut self,
label: impl Into<String>,
action: impl Into<String>,
) -> &mut Self {
self.args.insert(options::BUTTON2, Some(label.into()));
self
.args
.insert(options::BUTTON2_ACTION, Some(action.into()));
self
}
pub fn button3(
&mut self,
label: impl Into<String>,
action: impl Into<String>,
) -> &mut Self {
self.args.insert(options::BUTTON3, Some(label.into()));
self
.args
.insert(options::BUTTON3_ACTION, Some(action.into()));
self
}
pub fn show(&self) -> io::Result<RemoveHandle> {
ensure_success(&self.to_command().output()?)?;
let id = self.args.get(options::ID);
Ok(RemoveHandle::new(id.cloned().flatten()))
}
#[must_use]
pub fn to_command(&self) -> Command {
let mut cmd = Command::new("termux-notification");
for (key, val) in &self.args {
cmd.arg(key);
if let Some(val) = val {
cmd.arg(val);
}
}
cmd
}
}
fn ensure_success(output: &Output) -> io::Result<()> {
if output.status.success() {
Ok(())
} else {
Err(io::Error::other(stdout_stderr(output)))
}
}
fn stdout_stderr(output: &Output) -> String {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
[stdout, stderr]
.into_iter()
.filter(|s| !s.is_empty())
.collect::<Vec<_>>()
.join("\n")
}