feat(config): implement configuration file management

- add config.rs to handle program configuration
- create default configuration with retention rules
- implement save and load functions for persistent storage
- add credential file setting
This commit is contained in:
Jeremiah Russell
2025-10-07 15:51:54 +01:00
committed by Jeremiah Russell
parent 17dc58c4a7
commit 050f00940b

100
src/config.rs Normal file
View File

@@ -0,0 +1,100 @@
use std::{
env,
fs::{self, read_to_string},
path::PathBuf,
};
use serde::{Deserialize, Serialize};
mod eol_rule;
use eol_rule::EolRule;
use crate::{Error, MessageAge, Retention};
/// Configuration file for the program
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
credentials: Option<String>,
rules: Vec<EolRule>,
}
impl Default for Config {
fn default() -> Self {
let rules = Vec::new();
let mut cfg = Self {
credentials: Some("credential.json".to_string()),
rules,
};
cfg.add_rule(Retention::new(MessageAge::Years(1), true))
.add_rule(Retention::new(MessageAge::Weeks(1), true))
.add_rule(Retention::new(MessageAge::Months(1), true))
.add_rule(Retention::new(MessageAge::Years(5), true));
cfg
}
}
impl Config {
/// Create a new configuration file
pub fn new() -> Self {
Config::default()
}
/// Set a name for the credentials file
pub fn set_credentials(&mut self, file_name: &str) -> &mut Self {
self.credentials = Some(file_name.to_string());
self
}
/// Add a new rule to the rule set by setting the retention age
pub fn add_rule(&mut self, retention: Retention) -> &mut Self {
let id = if let Some(max) = self.rules.iter().max_by_key(|r| r.id()) {
max.id() + 1
} else {
1
};
let mut rule = EolRule::new(id);
rule.set_retention(retention);
self.rules.push(rule);
self
}
/// Save the current configuration to the file
pub fn save(&self) -> Result<(), Error> {
let home_dir = env::home_dir().unwrap();
let path = PathBuf::new()
.join(home_dir)
.join(".cull-gmail/cull-gmail.toml");
if let Ok(output) = toml::to_string(self) {
fs::write(path, output)?;
}
Ok(())
}
/// Load the current configuration
pub fn load() -> Result<Config, Error> {
let home_dir = env::home_dir().unwrap();
let path = PathBuf::new()
.join(home_dir)
.join(".cull-gmail/cull-gmail.toml");
let input = read_to_string(path)?;
let config = toml::from_str::<Config>(&input)?;
Ok(config)
}
/// Return the credential file name
pub fn credential_file(&self) -> &str {
if let Some(file) = &self.credentials {
file
} else {
""
}
}
}