use std::path::{Path, PathBuf};
use once_cell::sync::Lazy;
#[cfg(windows)]
pub use windows::Win32::UI::Shell::{FOLDERID_Profile, FOLDERID_RoamingAppData};
#[cfg(unix)]
use unix as sys;
#[cfg(windows)]
use win as sys;
#[cfg(windows)]
pub use win::{get_known_folder, set_known_folder};
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod win;
pub const TLD: &str = "com";
pub const COMPANY: &str = "shadow53";
pub const PROJECT: &str = "hoard";
pub const DATA_DIR_ENV: &str = "HOARD_DATA_DIR";
pub const CONFIG_DIR_ENV: &str = "HOARD_CONFIG_DIR";
static EMPTY_SPAN: Lazy<tracing::Span> = Lazy::new(|| tracing::trace_span!("get_dir_path"));
#[inline]
#[tracing::instrument(level = "trace")]
fn path_from_env(var: &str) -> Option<PathBuf> {
match std::env::var_os(var).map(PathBuf::from) {
None => {
tracing::trace!("could not find path in env var {}", var);
None
}
Some(path) => {
tracing::trace!("found {} = {}", var, path.display());
Some(path)
}
}
}
#[must_use]
#[inline]
pub fn home_dir() -> PathBuf {
let _span = tracing::trace_span!(parent: &*EMPTY_SPAN, "home_dir").entered();
sys::home_dir()
}
#[must_use]
#[inline]
pub fn config_dir() -> PathBuf {
let _span = tracing::trace_span!(parent: &*EMPTY_SPAN, "config_dir").entered();
path_from_env(CONFIG_DIR_ENV).unwrap_or_else(sys::config_dir)
}
#[must_use]
#[inline]
pub fn data_dir() -> PathBuf {
let _span = tracing::trace_span!(parent: &*EMPTY_SPAN, "data_dir").entered();
path_from_env(DATA_DIR_ENV).unwrap_or_else(sys::data_dir)
}
#[tracing::instrument(level = "trace")]
pub fn set_config_dir(path: &Path) {
std::env::set_var(CONFIG_DIR_ENV, path);
}
#[tracing::instrument(level = "trace")]
pub fn set_data_dir(path: &Path) {
std::env::set_var(DATA_DIR_ENV, path);
}
#[cfg(test)]
mod tests {
use std::env;
use super::*;
#[test]
fn test_env_config_dir() {
env::remove_var(CONFIG_DIR_ENV);
let original = config_dir();
let new_path = PathBuf::from("/env/config/dir");
assert_ne!(original, new_path);
set_config_dir(&new_path);
assert_eq!(new_path.as_os_str(), env::var_os(CONFIG_DIR_ENV).unwrap());
assert_eq!(new_path, config_dir());
}
#[test]
fn test_env_data_dir() {
env::remove_var(DATA_DIR_ENV);
let original = data_dir();
let new_path = PathBuf::from("/env/data/dir");
assert_ne!(original, new_path);
set_data_dir(&new_path);
assert_eq!(new_path.as_os_str(), env::var_os(DATA_DIR_ENV).unwrap());
assert_eq!(new_path, data_dir());
}
}