diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..824cd29 --- /dev/null +++ b/src/config.rs @@ -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, + rules: Vec, +} + +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 { + 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::(&input)?; + Ok(config) + } + + /// Return the credential file name + pub fn credential_file(&self) -> &str { + if let Some(file) = &self.credentials { + file + } else { + "" + } + } +}