Skip to main content

diskr/
history.rs

1use anyhow::{Context, Result};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use std::fs;
5use std::path::{Path, PathBuf};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct CleanEvent {
9    pub timestamp: DateTime<Utc>,
10    pub paths: Vec<PathBuf>,
11    pub bytes_freed: u64,
12    pub note: String,
13}
14
15#[derive(Debug, Default, Serialize, Deserialize)]
16pub struct History {
17    pub events: Vec<CleanEvent>,
18}
19
20fn history_path() -> Result<PathBuf> {
21    let base = dirs::data_local_dir().context("no local data dir")?;
22    Ok(base.join("diskr").join("history.json"))
23}
24
25pub fn load() -> Result<History> {
26    let path = history_path()?;
27    if !path.exists() {
28        return Ok(History::default());
29    }
30    let text = fs::read_to_string(&path)?;
31    Ok(serde_json::from_str(&text).unwrap_or_default())
32}
33
34pub fn append(event: CleanEvent) -> Result<()> {
35    let path = history_path()?;
36    if let Some(parent) = path.parent() {
37        fs::create_dir_all(parent)?;
38    }
39    let mut history = load()?;
40    history.events.push(event);
41    save(&path, &history)
42}
43
44pub fn last_event() -> Result<Option<CleanEvent>> {
45    Ok(load()?.events.last().cloned())
46}
47
48fn save(path: &Path, history: &History) -> Result<()> {
49    let text = serde_json::to_string_pretty(history)?;
50    fs::write(path, text)?;
51    Ok(())
52}