use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct NotificationState {
#[serde(default)]
pub notification_counts: HashMap<String, u32>,
}
impl NotificationState {
pub fn load() -> Result<Self> {
let state_path = Self::state_path();
if state_path.exists() {
let content = fs::read_to_string(&state_path)
.context("Failed to read notification state file")?;
toml::from_str(&content).context("Failed to parse notification state file")
} else {
Ok(Self::default())
}
}
pub fn save(&self) -> Result<()> {
let state_path = Self::state_path();
if let Some(parent) = state_path.parent() {
fs::create_dir_all(parent).context("Failed to create state directory")?;
}
let content =
toml::to_string_pretty(self).context("Failed to serialize notification state")?;
fs::write(&state_path, content).context("Failed to write notification state file")?;
Ok(())
}
fn state_path() -> PathBuf {
if let Ok(state_home) = std::env::var("XDG_STATE_HOME") {
PathBuf::from(state_home)
.join("relfa")
.join("notification_state.toml")
} else if let Some(home_dir) = dirs::home_dir() {
home_dir
.join(".local")
.join("state")
.join("relfa")
.join("notification_state.toml")
} else {
dirs::config_dir()
.map(|d| d.join("relfa").join("notification_state.toml"))
.unwrap_or_else(|| PathBuf::from("relfa").join("notification_state.toml"))
}
}
pub fn get_notification_count(&self, file_name: &str) -> u32 {
self.notification_counts
.get(file_name)
.copied()
.unwrap_or(0)
}
pub fn increment_notification_count(&mut self, file_name: &str) {
let count = self
.notification_counts
.entry(file_name.to_string())
.or_insert(0);
*count += 1;
}
pub fn reset_notification_count(&mut self, file_name: &str) {
self.notification_counts.remove(file_name);
}
pub fn retain_only_files(&mut self, current_files: &std::collections::HashSet<String>) {
self.notification_counts
.retain(|file_name, _| current_files.contains(file_name));
}
}