use home::home_dir;
use std::path::PathBuf;
use crate::fs::File;
#[cfg(not(windows))]
fn get_new_config_path(prefix: &str, filename: &str) -> Option<PathBuf> {
xdg::BaseDirectories::with_prefix(prefix)
.ok()
.and_then(|base| base.place_config_file(filename).ok())
}
#[cfg(windows)]
fn get_new_config_path(prefix: &str, filename: &str) -> Option<PathBuf> {
dirs::config_dir()
.map(|p| p.join(&format!("{}\\{}", prefix, filename)))
.find(|p| p.exists())
}
#[cfg(not(windows))]
pub fn locate_config(prefix: &str, filename: &str) -> Option<PathBuf> {
xdg::BaseDirectories::with_prefix(prefix)
.ok()
.and_then(|xdg| xdg.find_config_file(filename))
.or_else(|| {
xdg::BaseDirectories::new()
.ok()
.and_then(|fallback| fallback.find_config_file(format!("{prefix}.json")))
})
.or_else(|| {
if let Some(home_path) = home_dir() {
let fallback_path = format!(".config/{prefix}");
let fallback = home_path.join(fallback_path).join(filename);
if fallback.exists() {
return Some(fallback);
}
let fallback = home_path.join(format!(".{prefix}.json"));
if fallback.exists() {
return Some(fallback);
}
}
None
})
}
#[cfg(windows)]
pub fn locate_config(prefix: &str, filename: &str) -> Option<PathBuf> {
dirs::config_dir()
.map(|p| p.join(&format!("{}\\{}", prefix, filename)))
.filter(|p| p.exists())
}
pub fn init<T>(config: T, prefix: &str, filename: &str) -> crate::Result<PathBuf>
where
T: serde::Serialize + Default + File,
{
let config_path = locate_config(prefix, filename);
match config_path {
None => match get_new_config_path(prefix, filename) {
None => Err(crate::error::Error::Custom("Could not create file")),
Some(path) => {
config.write(&path)?;
Ok(path)
}
},
Some(path) => Ok(path),
}
}