You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

78 lines
2.2 KiB

use etcetera::BaseStrategy;
use std::path::PathBuf;
use crate::path_ext::PathExt;
fn xdg_dir(env: &str) -> Option<PathBuf> {
if cfg!(windows) {
let env_var = std::env::var(env).ok()?;
Some(PathBuf::from(env_var))
} else {
// On non-Windows platforms, `etcetera` already handles XDG variables
None
}
}
fn runtime_dir(basedirs: &impl BaseStrategy) -> Option<PathBuf> {
xdg_dir("XDG_RUNTIME_DIR").or_else(|| basedirs.runtime_dir())
}
fn state_dir(basedirs: &impl BaseStrategy) -> Option<PathBuf> {
xdg_dir("XDG_STATE_HOME").or_else(|| basedirs.state_dir())
}
fn cache_dir(basedirs: &impl BaseStrategy) -> PathBuf {
xdg_dir("XDG_CACHE_HOME").unwrap_or_else(|| basedirs.cache_dir())
}
/// A helper struct for directories in fnm that uses XDG Base Directory Specification
/// if applicable for the platform.
#[derive(Debug)]
pub struct Directories(
#[cfg(windows)] etcetera::base_strategy::Windows,
#[cfg(not(windows))] etcetera::base_strategy::Xdg,
);
impl Default for Directories {
fn default() -> Self {
Self(etcetera::choose_base_strategy().expect("choosing base strategy"))
}
}
impl Directories {
pub fn strategy(&self) -> &impl BaseStrategy {
&self.0
}
pub fn default_base_dir(&self) -> PathBuf {
let strategy = self.strategy();
let modern = strategy.data_dir().join("fnm");
if modern.exists() {
return modern;
}
let legacy = strategy.home_dir().join(".fnm");
if legacy.exists() {
return legacy;
}
#[cfg(target_os = "macos")]
{
let basedirs = etcetera::base_strategy::Apple::new().expect("Can't get home directory");
let legacy = basedirs.data_dir().join("fnm");
if legacy.exists() {
return legacy;
}
}
modern.ensure_exists_silently()
}
pub fn multishell_storage(&self) -> PathBuf {
let basedirs = self.strategy();
let dir = runtime_dir(basedirs)
.or_else(|| state_dir(basedirs))
.unwrap_or_else(|| cache_dir(basedirs));
dir.join("fnm_multishells")
}
}