use std::{ fs, path::{Path, PathBuf}, process, }; use serde::{Deserialize, Serialize}; use crate::error_reporting::{report_serde_json_err, report_serde_ron_err}; #[derive(Debug, Serialize, Deserialize)] pub struct Configs { #[serde(default = "default_example_value")] pub example_value: i32, #[serde(default = "default_no_startup_msg")] pub no_startup_message: bool, } /// what the fuck serde why do i need this fn default_example_value() -> i32 { 43 } fn default_no_startup_msg() -> bool { false } impl Configs { pub fn read(custom_path: Option) -> Self { use owo_colors::OwoColorize; let p = match custom_path { Some(p) => p, None => { let config_path = dirs::config_dir().expect("config dir should exist"); let ron_path = config_path.with_file_name("config.ron"); let json_path = config_path.with_file_name("config.json"); if Path::new(&ron_path).exists() { ron_path } else if Path::new(&json_path).exists() { json_path } else { eprintln!("{}: couldn't find config file", "Fatal error".red()); process::exit(1) } } }; match p.extension().map(|v| v.to_str().unwrap()) { Some("ron") => Self::read_json(&fs::read_to_string(p).unwrap()), Some("json") => Self::read_ron(&fs::read_to_string(p).unwrap()), None | Some(_) => { eprintln!( "{}: couldn't determine config file type", "Fatal error".red() ); process::exit(1) } } } pub fn read_json(config_text: &str) -> Configs { match serde_json::from_str(config_text) { Ok(c) => c, Err(e) => report_serde_json_err(config_text, e), } } pub fn read_ron(config_text: &str) -> Configs { match ron::from_str(config_text) { Ok(c) => c, Err(e) => report_serde_ron_err(config_text, e), } } }