///|
/// Standard directories for cache, config, data, and related paths (user-level, not app-specific).
/// On **Windows:** config/roaming from APPDATA, local/cache/data from LOCALAPPDATA.
/// On **Unix:** XDG_* when set, else \$HOME/.config, .cache, .local/share, .local/state.
pub struct BaseDirs {
home_dir : String
cache_dir : String
config_dir : String
config_local_dir : String
data_dir : String
data_local_dir : String
executable_dir : String?
preference_dir : String
runtime_dir : String?
state_dir : String?
}
///|
fn base_dirs_unix(home : String) -> BaseDirs {
let config = match get_env("XDG_CONFIG_HOME") {
Some(c) => c
None => join([home, ".config"])
}
let cache = match get_env("XDG_CACHE_HOME") {
Some(c) => c
None => join([home, ".cache"])
}
let data = match get_env("XDG_DATA_HOME") {
Some(d) => d
None => join([home, ".local", "share"])
}
let state = match get_env("XDG_STATE_HOME") {
Some(s) => s
None => join([home, ".local", "state"])
}
let exec_dir = match get_env("XDG_BIN_HOME") {
Some(b) => Some(b)
None => Some(join([home, ".local", "bin"]))
}
let runtime = get_env("XDG_RUNTIME_DIR")
BaseDirs::{
home_dir: home,
cache_dir: cache,
config_dir: config,
config_local_dir: config,
data_dir: data,
data_local_dir: data,
executable_dir: exec_dir,
preference_dir: config,
runtime_dir: runtime,
state_dir: Some(state),
}
}
///|
fn base_dirs_windows(home : String) -> BaseDirs {
let local_app_data = match get_env("LOCALAPPDATA") {
Some(p) => p
None => join([home, "AppData", "Local"])
}
let roaming = match get_env("APPDATA") {
Some(p) => p
None => join([home, "AppData", "Roaming"])
}
BaseDirs::{
home_dir: home,
cache_dir: local_app_data,
config_dir: roaming,
config_local_dir: local_app_data,
data_dir: local_app_data,
data_local_dir: local_app_data,
executable_dir: None,
preference_dir: roaming,
runtime_dir: None,
state_dir: None,
}
}
///|
/// Creates BaseDirs from the current environment. Returns `None` if home is not set
/// (HOME on Unix, USERPROFILE or HOME on Windows).
///
/// Example:
/// match BaseDirs::new() {
/// Some(base) => base.cache_dir() // e.g. /home/alice/.cache or %LOCALAPPDATA%
/// None => ...
/// }
pub fn BaseDirs::new() -> BaseDirs? {
match home_dir() {
Some(home) =>
Some(
if is_windows() {
base_dirs_windows(home)
} else {
base_dirs_unix(home)
},
)
None => None
}
}
///|
/// User home directory (e.g. /home/alice or C:\Users\alice).
pub fn BaseDirs::home_dir(self : BaseDirs) -> String {
self.home_dir
}
///|
/// Cache directory (e.g. .cache on Unix, LOCALAPPDATA on Windows).
pub fn BaseDirs::cache_dir(self : BaseDirs) -> String {
self.cache_dir
}
///|
/// Config directory (roaming on Windows: APPDATA; Unix: XDG_CONFIG_HOME or .config).
pub fn BaseDirs::config_dir(self : BaseDirs) -> String {
self.config_dir
}
///|
/// Local config directory (LOCALAPPDATA on Windows; same as config_dir on Unix).
pub fn BaseDirs::config_local_dir(self : BaseDirs) -> String {
self.config_local_dir
}
///|
/// Data directory (e.g. .local/share on Unix, LOCALAPPDATA on Windows).
pub fn BaseDirs::data_dir(self : BaseDirs) -> String {
self.data_dir
}
///|
/// Local data directory (same as data_dir on both platforms in v1).
pub fn BaseDirs::data_local_dir(self : BaseDirs) -> String {
self.data_local_dir
}
///|
/// User executables directory (XDG_BIN_HOME or .local/bin on Unix); None on Windows.
pub fn BaseDirs::executable_dir(self : BaseDirs) -> String? {
self.executable_dir
}
///|
/// Preference/settings directory (same as config_dir on Unix; APPDATA on Windows).
pub fn BaseDirs::preference_dir(self : BaseDirs) -> String {
self.preference_dir
}
///|
/// Runtime directory (XDG_RUNTIME_DIR on Unix); None on Windows.
pub fn BaseDirs::runtime_dir(self : BaseDirs) -> String? {
self.runtime_dir
}
///|
/// State directory (XDG_STATE_HOME or .local/state on Unix); None on Windows.
pub fn BaseDirs::state_dir(self : BaseDirs) -> String? {
self.state_dir
}