use serde::{Deserialize, Serialize};
use serde_yaml::Value;
use std::io::Write;
use std::{env, fs, path::PathBuf};
#[derive(Debug, Serialize, Deserialize)]
pub struct AppConfig {
pub database: String,
pub language: String,
}
impl Default for AppConfig {
fn default() -> Self {
let database = default_db_path();
Self {
database: database.to_string_lossy().to_string(),
language: "en".to_string(),
}
}
}
fn config_dir() -> PathBuf {
if cfg!(target_os = "windows") {
if let Ok(appdata) = env::var("APPDATA") {
let mut path = PathBuf::from(appdata);
path.push("librius");
return path;
}
} else if let Ok(home) = env::var("HOME") {
let mut path = PathBuf::from(home);
path.push(".librius");
return path;
}
PathBuf::from(".librius")
}
fn default_db_path() -> PathBuf {
let mut path = config_dir();
fs::create_dir_all(&path).ok();
path.push("librius.sqlite");
path
}
pub fn config_file_path() -> PathBuf {
let mut path = config_dir();
fs::create_dir_all(&path).ok();
path.push("librius.conf");
path
}
pub fn load_or_init() -> Result<AppConfig, Box<dyn std::error::Error>> {
let config_path = config_file_path();
if config_path.exists() {
let contents = fs::read_to_string(&config_path)?;
let cfg: AppConfig = serde_yaml::from_str(&contents)?;
Ok(cfg)
} else {
let cfg = AppConfig::default();
let yaml = serde_yaml::to_string(&cfg)?;
let mut file = fs::File::create(&config_path)?;
file.write_all(yaml.as_bytes())?;
Ok(cfg)
}
}
pub fn load_language_from_conf() -> Option<String> {
let conf_path = config_file_path();
if !conf_path.exists() {
return None;
}
let content = fs::read_to_string(conf_path).ok()?;
let yaml: Value = serde_yaml::from_str(&content).ok()?;
yaml.get("language")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
}