1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
//! Basic config API
//!
//! Contains a special trait that allows a type to have an associated toml config file
use serde::{Deserialize, Serialize};
use std::io;
use std::fs;
/// The Config trait allows a type to have an associated toml config file\
///
/// Requires the Default, Serialize, and Deserialize traits (can be derived) to be implemented
pub trait Config: Serialize + Default + for <'de> Deserialize<'de> {
/// This constant must be set to the file name of the config file
const FILE_NAME: &'static str;
/// Returns the save directory of the config file.
///
/// This method must be defined
fn get_save_dir() -> String;
/// Returns the full path of the config file
fn get_full_path() -> String { format!("{}/{}", Self::get_save_dir(), Self::FILE_NAME) }
/// Load from the config file
///
/// Returns the defaults if the file does not exist or is corrupted
///
/// Panics if the config directory cannot be created
fn load() -> Self {
let mut config = Self::default();
let toml = match fs::read_to_string(Self::get_full_path()) {
Ok(file) => file,
Err(_) => {
config.save().expect("Unable to save config!");
return config;
}
};
match toml::from_str(&toml) {
Err(_) => return Self::default(),
Ok(t) => config = t
}
config
}
/// Save to the config file
///
/// It is recommended to call this in every method that has &mut self as an argument!
fn save(&self) -> io::Result<()> {
let toml = toml::to_string_pretty(&self).unwrap();
fs::create_dir_all(Self::get_save_dir())?;
fs::write(Self::get_full_path(), toml)
}
}