1use anyhow::{Context, Result};
2use serde::{Deserialize, Serialize};
3use std::fs;
4use std::path::PathBuf;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Config {
8 pub min_file_size_mb: u64,
9 pub stale_days: i64,
10 pub stale_min_size_mb: u64,
11 pub exclude_paths: Vec<String>,
12 pub watch_duration_hours: u64,
13 pub duplicate_min_size_kb: u64,
14 pub cross_filesystems: bool,
15 pub use_trash: bool,
16}
17
18impl Default for Config {
19 fn default() -> Self {
20 Self {
21 min_file_size_mb: 100,
22 stale_days: 180,
23 stale_min_size_mb: 50,
24 exclude_paths: vec!["/proc".into(), "/sys".into(), "/dev".into()],
25 watch_duration_hours: 24,
26 duplicate_min_size_kb: 4,
27 cross_filesystems: false,
28 use_trash: true,
29 }
30 }
31}
32
33pub fn config_path() -> Result<PathBuf> {
34 let base = dirs::config_dir().context("no config dir")?;
35 Ok(base.join("diskr").join("config.toml"))
36}
37
38pub fn load() -> Result<Config> {
39 let path = config_path()?;
40 if !path.exists() {
41 let cfg = Config::default();
42 save(&cfg)?;
43 return Ok(cfg);
44 }
45 let text = fs::read_to_string(&path)?;
46 Ok(toml::from_str(&text).unwrap_or_default())
47}
48
49pub fn save(cfg: &Config) -> Result<()> {
50 let path = config_path()?;
51 if let Some(parent) = path.parent() {
52 fs::create_dir_all(parent)?;
53 }
54 let text = toml::to_string_pretty(cfg)?;
55 fs::write(path, text)?;
56 Ok(())
57}