sxmotify/namespace.rs
1use crate::{clear_notification, notification_directory, set_notification};
2use std::{fs, io, path};
3
4/// A namespace for sxmo notifications. The namespace is associated with a prefix provided during
5/// construction. Any notification additionally has an ID, which has to be unique within the
6/// namespace. The nofications are created as files in the form $prefix-$id, so keep both the
7/// variables filename-friendly (e.g. by escaping or hashing potentially unsafe IDs), or bad
8/// things can happen.
9pub struct Namespace {
10 prefix: String,
11}
12
13impl Namespace {
14 /// Create a notification namespace using the provided prefix.
15 pub fn new(prefix: String) -> Self {
16 Namespace { prefix }
17 }
18
19 fn namespaced(&self, id: String) -> String {
20 format!("{}-{}", self.prefix, id)
21 }
22
23 /// Set the notification with the provided ID. This will override any previous notifications
24 /// with that ID.
25 pub fn set_notification(
26 &self,
27 id: String,
28 text: String,
29 command: String,
30 watched_file: Option<&path::Path>,
31 ) -> io::Result<()> {
32 set_notification(self.namespaced(id), text, command, watched_file)
33 }
34
35 /// Clear the notification with a given ID. If successful, it guarantees no notification with
36 /// this ID exists anymore.
37 pub fn clear_notification(&self, id: String) -> io::Result<()> {
38 clear_notification(self.namespaced(id))
39 }
40
41 /// Clean up the namespace, removing all notifications within it. Will attempt to remove all
42 /// notifications it is able to locate, disregarding errors. Returns only the last error
43 /// encountered, sorry.
44 pub fn cleanup(self) -> io::Result<()> {
45 let Self { prefix } = self;
46 fs::read_dir(notification_directory())?
47 .filter_map(|f| Some(f.ok()?.path()))
48 .filter_map(|f| {
49 if f.file_name()?.to_str()?.starts_with(&prefix) {
50 Some(f)
51 } else {
52 None
53 }
54 })
55 .fold(Ok(()), |e, f| {
56 fs::remove_file(f)?;
57 e
58 })
59 }
60}