use std::env;
use std::path::PathBuf;
use crate::APP_NAME;
pub fn home_dir() -> Option<PathBuf> {
if let Ok(home) = env::var("HOME")
&& !home.is_empty()
{
return Some(PathBuf::from(home));
}
if let Ok(profile) = env::var("USERPROFILE")
&& !profile.is_empty()
{
return Some(PathBuf::from(profile));
}
match (env::var("HOMEDRIVE"), env::var("HOMEPATH")) {
(Ok(drive), Ok(path)) if !drive.is_empty() && !path.is_empty() => {
Some(PathBuf::from(format!("{drive}{path}")))
}
_ => None,
}
}
pub fn expand_tilde(path: &str) -> PathBuf {
if path == "~" {
return home_dir().unwrap_or_else(|| PathBuf::from(path));
}
if let Some(rest) = path.strip_prefix("~/")
&& let Some(home) = home_dir()
{
return home.join(rest);
}
PathBuf::from(path)
}
fn xdg_dir(env_var: &str, fallback: &str) -> PathBuf {
if let Ok(base) = env::var(env_var)
&& !base.is_empty()
{
return PathBuf::from(base).join(APP_NAME);
}
let home = home_dir().unwrap_or_else(|| PathBuf::from("."));
home.join(fallback).join(APP_NAME)
}
pub fn config_dir() -> PathBuf {
xdg_dir("XDG_CONFIG_HOME", ".config")
}
pub fn state_dir() -> PathBuf {
xdg_dir("XDG_STATE_HOME", ".local/state")
}
pub fn config_file() -> PathBuf {
config_dir().join("config.toml")
}
pub fn state_file() -> PathBuf {
state_dir().join("state.toml")
}
pub fn log_file() -> PathBuf {
state_dir().join("calcli.log")
}