From 3247828672f4c42c7c59ddf14854f7275a550a0b Mon Sep 17 00:00:00 2001 From: Samuel Lorch Date: Sat, 21 Oct 2023 23:34:27 +0200 Subject: [PATCH] add config manager --- src/config_manager.rs | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/config_manager.rs diff --git a/src/config_manager.rs b/src/config_manager.rs new file mode 100644 index 0000000..6e1cbc9 --- /dev/null +++ b/src/config_manager.rs @@ -0,0 +1,82 @@ +use validator::Validate; + +use super::definitions::config::Config; +use std::error::Error; +use std::fs; + +const CURRENT_CONFIG_PATH: &str = "config.json"; +const PENDING_CONFIG_PATH: &str = "pending.json"; + +pub struct ConfigManager { + current_config: Config, + pending_config: Config, +} + +impl ConfigManager { + pub fn get_current_config(&self) -> Config { + self.current_config.clone() + } + + pub fn get_pending_config(&self) -> Config { + self.pending_config.clone() + } + + pub fn apply_pending_changes(&mut self) -> Result<(), Box> { + // TODO run Apply functions, revert on failure + write_config_to_file(CURRENT_CONFIG_PATH, self.pending_config.clone())?; + // Also revert if config save fails + self.current_config = self.pending_config.clone(); + Ok(()) + } + + pub fn discard_pending_changes(&mut self) -> Result<(), Box> { + self.pending_config = self.current_config.clone(); + Ok(()) + } + + pub fn start_transaction(&mut self) -> Result> { + Ok(ConfigTransaction { + finished: false, + //guard: guard, + changes: self.pending_config.clone(), + config_manager: self, + }) + } +} + +pub struct ConfigTransaction<'a> { + finished: bool, + config_manager: &'a mut ConfigManager, + pub changes: Config, +} + +impl<'a> ConfigTransaction<'a> { + pub fn commit(&mut self) -> Result<(), Box> { + let ch = self.changes.clone(); + ch.validate()?; + self.config_manager.pending_config = ch.clone(); + Ok(()) + } +} + +pub fn new_config_manager() -> Result> { + Ok(ConfigManager { + current_config: read_file_to_config(CURRENT_CONFIG_PATH)?, + pending_config: read_file_to_config(PENDING_CONFIG_PATH)?, + }) +} + +fn read_file_to_config(path: &str) -> Result> { + let data = fs::read_to_string(path)?; + let conf: Config = serde_json::from_str(&data)?; + if conf.config_version != 1 { + // return Err("Unsupported config Version"); + } + Ok(conf) +} + +fn write_config_to_file(path: &str, conf: Config) -> Result<(), Box> { + let data: String = serde_json::to_string_pretty(&conf)?; + fs::write(path, data)?; + Ok(()) +}