Skip to main content

thor_notify/
state.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashSet;
3use std::path::PathBuf;
4
5#[derive(Debug, Default, Serialize, Deserialize)]
6pub struct InboxState {
7    pub read: HashSet<String>,
8    pub archived: HashSet<String>,
9}
10
11impl InboxState {
12    /// Get state file path
13    pub fn path() -> PathBuf {
14        dirs::data_dir()
15            .unwrap_or_else(|| PathBuf::from("."))
16            .join("thor")
17            .join("state.json")
18    }
19
20    /// Load state from disk
21    pub async fn load() -> Self {
22        let path = Self::path();
23        if path.exists() {
24            tokio::fs::read_to_string(&path)
25                .await
26                .ok()
27                .and_then(|s| serde_json::from_str(&s).ok())
28                .unwrap_or_default()
29        } else {
30            Self::default()
31        }
32    }
33
34    /// Save state to disk
35    pub async fn save(&self) -> std::io::Result<()> {
36        let path = Self::path();
37        if let Some(parent) = path.parent() {
38            tokio::fs::create_dir_all(parent).await?;
39        }
40        let json = serde_json::to_string_pretty(self)?;
41        tokio::fs::write(path, json).await
42    }
43
44    /// Mark notification as read
45    pub fn mark_read(&mut self, id: &str) {
46        self.read.insert(id.to_string());
47    }
48
49    /// Mark notification as archived
50    pub fn mark_archived(&mut self, id: &str) {
51        self.archived.insert(id.to_string());
52    }
53
54    /// Check if notification is read
55    pub fn is_read(&self, id: &str) -> bool {
56        self.read.contains(id)
57    }
58
59    /// Check if notification is archived
60    pub fn is_archived(&self, id: &str) -> bool {
61        self.archived.contains(id)
62    }
63
64    /// Get unread count from a list of notification IDs
65    pub fn unread_count(&self, ids: &[String]) -> usize {
66        ids.iter().filter(|id| !self.is_read(id) && !self.is_archived(id)).count()
67    }
68}