slightly more graceful config reading: reads entry by entry
reads from default only if an entry is not present, and then writes those defaults to the file if anything was changed
This commit is contained in:
parent
6c727b056e
commit
73f511775e
1 changed files with 61 additions and 17 deletions
|
|
@ -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<TomlError> for ReadError {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
pub fn load_from_file(filename: &str) -> Result<Self, ReadError> {
|
||||
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<Value, _> = 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<dyn std::error::Error>> {
|
||||
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
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue