use std::{ fs::{create_dir_all, File}, io::{Read, Write}, path::Path, }; use serde::{Deserialize, Serialize}; use crate::{db::db_setup, error::MLE}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Cfg { pub data: String, pub cache: String, pub apis: Apis, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Apis { pub modrinth: String, } impl Cfg { pub fn init(path: Option) -> MLE { let configfile = match path.clone() { Some(p) => String::from(p), None => dirs::config_dir() .unwrap() .join("modlist.toml") .to_string_lossy() .to_string(), }; let mut file = match File::open(&configfile) { Ok(file) => file, Err(err) => { if err.kind() == std::io::ErrorKind::NotFound && path.is_none() { create_config(&configfile)?; File::open(&configfile)? } else { return Err(err.into()); } } }; let mut content = String::new(); file.read_to_string(&mut content)?; let config = toml::from_str::(&content)?; //Check cache if !Path::new(&config.cache).exists() { create_cache(&config.cache)?; }; //Check database //TODO check file let datafile = format!("{}/data.db", config.data); match File::open(&datafile) { Ok(..) => (), Err(..) => create_database(&datafile)?, }; Ok(config) } } fn create_config(path: &str) -> MLE<()> { print!("No config file found, create default"); //Force flush of stdout, else print! doesn't print instantly std::io::stdout().flush()?; let default_cfg = Cfg { //TODO get home dir data: String::from("$HOME/.cache/modlist/"), cache: String::from("$HOME/.cache/modlist/cache"), apis: Apis { modrinth: String::from("https://api.modrinth.com/v2/"), }, }; let mut file = File::create(path)?; file.write_all(toml::to_string(&default_cfg)?.as_bytes())?; println!(" ✓"); Ok(()) } fn create_database(path: &str) -> MLE<()> { print!("No database found, create base"); //Force flush of stdout, else print! doesn't print instantly std::io::stdout().flush()?; File::create(path)?; db_setup(path)?; println!(" ✓"); Ok(()) } fn create_cache(path: &str) -> MLE<()> { print!("No cache direcory found, create one"); //Force flush of stdout, else print! doesn't print instantly std::io::stdout().flush()?; create_dir_all(path)?; println!(" ✓"); Ok(()) }