diff --git a/src/config/mod.rs b/src/config/mod.rs index ac22321..ecfa975 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -7,6 +7,7 @@ mod load; use rltk::prelude::*; use toml::de::Error as TomlError; +use toml::Value; use serde::{ Serialize, Deserialize }; lazy_static! { @@ -69,10 +70,25 @@ impl From for ReadError { } impl Config { - pub fn load_from_file(filename: &str) -> Result { - let contents = std::fs::read_to_string(filename).map_err(|e| ReadError::Io(e))?; - let config: Config = toml::from_str(&contents).map_err(|e| ReadError::Toml(e))?; - return Ok(config); + pub fn load_from_file(filename: &str) -> Config { + if let Ok(contents) = std::fs::read_to_string(filename) { + let parsed_config: Result = toml::from_str(&contents); + if let Ok(parsed_config) = parsed_config { + let mut config = Config::default(); + let mut requires_write = false; + requires_write |= config.logging.apply_values(&parsed_config); + requires_write |= config.visuals.apply_values(&parsed_config); + + if requires_write { + if let Err(write_err) = config.save_to_file(filename) { + eprintln!("Error writing config: {:?}", write_err); + } + } + + return config; + } + } + Config::default() } pub fn save_to_file(&self, filename: &str) -> Result<(), Box> { let toml_string = toml::to_string(self)?; @@ -81,23 +97,51 @@ impl Config { } } -#[cfg(not(target_arch = "wasm32"))] -pub fn try_load_configuration() -> Config { - let config: Config = match Config::load_from_file("config.toml") { - Ok(config) => { - console::log(format!("Successfully loaded config: {:?}", config)); - config - } - Err(e) => { - console::log(format!("Error loading config: {:?}", e)); - let config = Config::default(); - if let Err(write_err) = config.save_to_file("config.toml") { - eprintln!("Error writing default config: {:?}", write_err); +macro_rules! apply_bool_value { + ($config:expr, $parsed_config:expr, $changed:expr, $field:ident) => { + if let Some(value) = $parsed_config.get(stringify!($field)).and_then(|v| v.as_bool()) { + if $config.$field != value { + $config.$field = value; + $changed = true; } - config } }; +} +trait Section { + fn apply_values(&mut self, parsed_config: &Value) -> bool; +} + +impl Section for LogConfig { + fn apply_values(&mut self, parsed_config: &Value) -> bool { + if let Some(section) = parsed_config.get("logging") { + let mut missing = false; + apply_bool_value!(self, section, missing, log_spawning); + apply_bool_value!(self, section, missing, log_ticks); + missing + } else { + true + } + } +} + +impl Section for VisualConfig { + fn apply_values(&mut self, parsed_config: &Value) -> bool { + if let Some(section) = parsed_config.get("visuals") { + let mut missing = false; + apply_bool_value!(self, section, missing, with_scanlines); + apply_bool_value!(self, section, missing, with_screen_burn); + apply_bool_value!(self, section, missing, with_darken_by_distance); + missing + } else { + true + } + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn try_load_configuration() -> Config { + let config: Config = Config::load_from_file("config.toml"); return config; }