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 rltk::prelude::*;
|
||||||
use toml::de::Error as TomlError;
|
use toml::de::Error as TomlError;
|
||||||
|
use toml::Value;
|
||||||
use serde::{ Serialize, Deserialize };
|
use serde::{ Serialize, Deserialize };
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
|
@ -69,10 +70,25 @@ impl From<TomlError> for ReadError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn load_from_file(filename: &str) -> Result<Self, ReadError> {
|
pub fn load_from_file(filename: &str) -> Config {
|
||||||
let contents = std::fs::read_to_string(filename).map_err(|e| ReadError::Io(e))?;
|
if let Ok(contents) = std::fs::read_to_string(filename) {
|
||||||
let config: Config = toml::from_str(&contents).map_err(|e| ReadError::Toml(e))?;
|
let parsed_config: Result<Value, _> = toml::from_str(&contents);
|
||||||
return Ok(config);
|
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>> {
|
pub fn save_to_file(&self, filename: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let toml_string = toml::to_string(self)?;
|
let toml_string = toml::to_string(self)?;
|
||||||
|
|
@ -81,23 +97,51 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
macro_rules! apply_bool_value {
|
||||||
pub fn try_load_configuration() -> Config {
|
($config:expr, $parsed_config:expr, $changed:expr, $field:ident) => {
|
||||||
let config: Config = match Config::load_from_file("config.toml") {
|
if let Some(value) = $parsed_config.get(stringify!($field)).and_then(|v| v.as_bool()) {
|
||||||
Ok(config) => {
|
if $config.$field != value {
|
||||||
console::log(format!("Successfully loaded config: {:?}", config));
|
$config.$field = value;
|
||||||
config
|
$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;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue