use anyhow::Result; use directories::ProjectDirs; use serde::{Deserialize, Serialize}; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::time::Duration; const SETTINGS_FILE: &str = "settings.toml"; #[derive(Clone, Serialize, Deserialize, Debug)] pub struct Config { pub work_time: Duration, pub short_break: Duration, pub long_break: Duration, pub sound_file: Option, } impl Config { pub fn new(work: u64, short_break: u64, long_break: u64) -> Self { Self::init_directories(); Config { work_time: Duration::from_secs(work), short_break: Duration::from_secs(short_break), long_break: Duration::from_secs(long_break), sound_file: None, } } fn init_directories() { let config_dir = Self::get_config_directory(); let data_dir = Self::get_data_directory(); if !config_dir.exists() { let _ = fs::create_dir_all(config_dir); } if !data_dir.exists() { let _ = fs::create_dir_all(data_dir); } } pub fn save(config: &Config) -> Result<()> { let config_directory = Self::get_config_directory(); if !config_directory.exists() { fs::create_dir_all(&config_directory)?; } Self::write_to_file(&config_directory.join(SETTINGS_FILE), config) } pub fn load() -> Option { let config_file = Self::get_config_directory().join(SETTINGS_FILE); Self::read_from_file(&config_file).ok() } fn write_to_file>(path: &P, cfg: &Self) -> Result<()> { let mut new_file = File::create(path.as_ref())?; let serialized = toml::to_string(cfg)?; Ok(new_file.write_all(serialized.as_bytes())?) } fn read_from_file>(path: &P) -> Result { let mut toml_buf = vec![]; let mut file = File::open(path.as_ref())?; file.read_to_end(&mut toml_buf)?; Ok(toml::from_slice(&toml_buf)?) } pub fn get_data_directory() -> PathBuf { ProjectDirs::from("moe", "paoda", "domasi") .unwrap() .config_dir() .to_path_buf() } fn get_config_directory() -> PathBuf { ProjectDirs::from("moe", "paoda", "domasi") .unwrap() .data_dir() .to_path_buf() } } impl Default for Config { fn default() -> Self { Config::new(1500, 300, 600) } }