sxmotify/
basic.rs

1use crate::notification_directory;
2use std::{fs, io, path};
3
4const NONEXISTENT_PATH: &str = "/no/such/file/at/all";
5
6fn path_in_directory(file_name: String) -> path::PathBuf {
7    let mut result = notification_directory();
8    result.push(file_name);
9    result
10}
11
12fn file_path(id: &str) -> path::PathBuf {
13    path_in_directory(format!("{}", id))
14}
15
16fn temp_file_path(id: &str) -> path::PathBuf {
17    path_in_directory(format!("{}~", id))
18}
19
20fn add_autoremoval(command: String, file_path: &path::Path) -> String {
21    format!("rm -f {}; {}", file_path.display(), command)
22}
23
24fn format_notification(text: String, command: String, watched_file: &path::Path) -> String {
25    format!(
26        "{}\n{}\n{}\n",
27        command,
28        watched_file.to_string_lossy(),
29        text
30    )
31}
32
33/// Set the notification with the provided ID. This will override any previous notifications
34/// with that ID.
35pub fn set_notification(
36    id: String,
37    text: String,
38    command: String,
39    watched_file: Option<&path::Path>,
40) -> io::Result<()> {
41    let nonexistent_path = path::PathBuf::from(NONEXISTENT_PATH);
42    let watched_file = match watched_file {
43        Some(watched_file) => watched_file,
44        None => &nonexistent_path,
45    };
46    let temp_file_name = temp_file_path(&id);
47    let file_name = file_path(&id);
48    let notification = format_notification(
49        text,
50        add_autoremoval(command, file_name.as_path()),
51        watched_file,
52    );
53    fs::write(temp_file_name.as_path(), notification)?;
54    fs::rename(temp_file_name, file_name)
55}
56
57/// Clear the notification with a given ID. If successful, it guarantees no notification with
58/// this ID exists anymore.
59pub fn clear_notification(id: String) -> io::Result<()> {
60    let file_name = file_path(&id);
61    match fs::remove_file(file_name) {
62        Ok(()) => Ok(()),
63        Err(e) => {
64            if e.kind() == io::ErrorKind::NotFound {
65                // Ignore not found, as the notification is cleared.
66                Ok(())
67            } else {
68                Err(e)
69            }
70        }
71    }
72}