use crate::prelude::*;
use std::sync::LazyLock;
#[cfg(test)]
use crate::tests::evloop::TempPathConfig;
pub const XDG_CONFIG_HOME: &str = "XDG_CONFIG_HOME";
pub const HOME: &str = "HOME";
pub const XDG_CACHE_HOME: &str = "XDG_CACHE_HOME";
pub const XDG_DATA_HOME: &str = "XDG_DATA_HOME";
fn _dirs_config_dir() -> Option<PathBuf> {
dirs::config_dir()
}
fn _dirs_home_dir() -> Option<PathBuf> {
dirs::home_dir()
}
fn _dirs_cache_dir() -> Option<PathBuf> {
dirs::cache_dir()
}
fn _dirs_data_dir() -> Option<PathBuf> {
dirs::data_dir()
}
fn _xdg_config_dir(config_dir: &Path) -> PathBuf {
config_dir.join("rsvim").to_path_buf()
}
fn _home_dir(home_dir: &Path) -> PathBuf {
home_dir.join(".rsvim")
}
fn find_config_home_and_entry(
config_dir: &Path,
home_dir: &Path,
) -> (
/* config_home */ PathBuf,
/* config_entry */ Option<PathBuf>,
) {
for config_dir in [_xdg_config_dir(config_dir), _home_dir(home_dir)].iter() {
let ts_config = config_dir.join("rsvim.ts");
if ts_config.as_path().exists() {
return (config_dir.to_path_buf(), Some(ts_config));
}
let js_config = config_dir.join("rsvim.js");
if js_config.as_path().exists() {
return (config_dir.to_path_buf(), Some(js_config));
}
}
for config_entry in [
home_dir.join(".rsvim.ts").to_path_buf(),
home_dir.join(".rsvim.js").to_path_buf(),
]
.iter()
{
if config_entry.exists() {
return (_home_dir(home_dir), Some(config_entry.clone()));
}
}
(_home_dir(home_dir), None)
}
fn _xdg_cache_dir(cache_dir: &Path) -> PathBuf {
let folder = if cfg!(target_family = "windows") {
"rsvim-cache"
} else {
"rsvim"
};
cache_dir.join(folder).to_path_buf()
}
fn _xdg_data_dir(data_dir: &Path) -> PathBuf {
let folder = if cfg!(target_family = "windows") {
"rsvim-data"
} else {
"rsvim"
};
data_dir.join(folder).to_path_buf()
}
#[derive(Debug, Clone)]
pub struct PathConfig {
config_entry: Option<PathBuf>,
config_home: PathBuf,
cache_home: PathBuf,
data_home: PathBuf,
}
impl PathConfig {
fn _new_internal(
config_dir: PathBuf,
home_dir: PathBuf,
cache_dir: PathBuf,
data_dir: PathBuf,
) -> Self {
let config_home_and_entry =
find_config_home_and_entry(&config_dir, &home_dir);
Self {
config_home: config_home_and_entry.0,
config_entry: config_home_and_entry.1,
cache_home: _xdg_cache_dir(&cache_dir),
data_home: _xdg_data_dir(&data_dir),
}
}
pub fn new() -> Self {
let config_dir = _dirs_config_dir().unwrap();
let home_dir = _dirs_home_dir().unwrap();
let cache_dir = _dirs_cache_dir().unwrap();
let data_dir = _dirs_data_dir().unwrap();
Self::_new_internal(config_dir, home_dir, cache_dir, data_dir)
}
#[cfg(test)]
pub fn _new_with_temp_path(tp: &TempPathConfig) -> Self {
Self::_new_internal(
tp.xdg_config_home.clone(),
tp.home_dir.clone(),
tp.xdg_cache_home.clone(),
tp.xdg_data_home.clone(),
)
}
#[cfg(not(test))]
pub fn config_entry(&self) -> &Option<PathBuf> {
&self.config_entry
}
#[cfg(test)]
pub fn config_entry(&self) -> Option<PathBuf> {
use crate::tests::evloop::TEMP_PATH_CONFIG;
TEMP_PATH_CONFIG.with_borrow(|tp| {
Self::_new_with_temp_path(tp.as_ref().unwrap())
.config_entry
.clone()
})
}
#[cfg(not(test))]
pub fn config_home(&self) -> &PathBuf {
&self.config_home
}
#[cfg(test)]
pub fn config_home(&self) -> PathBuf {
use crate::tests::evloop::TEMP_PATH_CONFIG;
TEMP_PATH_CONFIG.with_borrow(|tp| {
Self::_new_with_temp_path(tp.as_ref().unwrap())
.config_home
.clone()
})
}
#[cfg(not(test))]
pub fn cache_home(&self) -> &PathBuf {
&self.cache_home
}
#[cfg(test)]
pub fn cache_home(&self) -> PathBuf {
use crate::tests::evloop::TEMP_PATH_CONFIG;
TEMP_PATH_CONFIG.with_borrow(|tp| {
Self::_new_with_temp_path(tp.as_ref().unwrap())
.cache_home
.clone()
})
}
#[cfg(not(test))]
pub fn data_home(&self) -> &PathBuf {
&self.data_home
}
#[cfg(test)]
pub fn data_home(&self) -> PathBuf {
use crate::tests::evloop::TEMP_PATH_CONFIG;
TEMP_PATH_CONFIG.with_borrow(|tp| {
Self::_new_with_temp_path(tp.as_ref().unwrap())
.data_home
.clone()
})
}
}
pub static PATH_CONFIG: LazyLock<PathConfig> = LazyLock::new(PathConfig::new);