use crate::environ::EnvVal;
use crate::local::LocalInfo;
use camino::{Utf8Path, Utf8PathBuf};
pub struct Info {
home: Utf8PathBuf,
app_name: String,
master: Utf8PathBuf,
minion: Option<Utf8PathBuf>,
}
impl Info {
pub fn new<T>(app_name: &str, home: &T) -> Self
where
T: AsRef<Utf8Path> + ?Sized,
{
let app_name = app_name.to_owned();
let home = home.as_ref().to_owned();
let master = home.join("Library").join("Application Support");
let minion = Self::get_minion(&home, &master);
Self {
home,
app_name,
master,
minion,
}
}
fn get_minion(home: &Utf8Path, master: &Utf8Path) -> Option<Utf8PathBuf> {
let minion = home.join("Library").join("ApplicationSupport");
if !minion.exists() {
return None;
}
if !minion.is_dir() {
return None;
}
if !minion.is_symlink() {
return None;
}
if let Some(source) = Self::get_link_source(&minion) {
if source == master {
return Some(minion);
}
}
None
}
fn get_link_source(path: &Utf8Path) -> Option<Utf8PathBuf> {
if !path.is_symlink() {
return None;
}
if let Ok(source) = path.read_link_utf8() {
if source.is_absolute() {
return Some(source);
}
if let Some(parent) = path.parent() {
let parent = parent.join(source);
if let Ok(source) = parent.canonicalize_utf8() {
return Some(source);
}
}
}
None
}
fn is_proper(&self, path: &Utf8Path) -> bool {
if let Some(path_source) = Self::get_link_source(path) {
if path_source == *self.master {
return true;
}
if let Some(minion) = self.minion.as_ref() {
if *path_source == *minion {
return true;
}
}
return false;
}
if *path == *self.master {
return true;
}
if let Some(minion) = self.minion.as_ref() {
if *path == *minion {
return true;
}
}
false
}
}
impl LocalInfo for Info {
fn get_cache_home(&self) -> Utf8PathBuf {
let default = self.home.join("Library").join("Caches");
let path: Utf8PathBuf = EnvVal::from("XDG_CACHE_HOME")
.with_default_value(&default)
.into();
if path.exists() && path.is_dir() {
if self.is_proper(&path) {
return path.join(&self.app_name).join("cache");
}
return path.join(&self.app_name);
}
self.home.join(".cache").join(&self.app_name)
}
fn get_config_home(&self) -> Utf8PathBuf {
let default = self.home.join("Library").join("Application Support");
let path: Utf8PathBuf = EnvVal::from("XDG_CONFIG_HOME")
.with_default_value(&default)
.into();
if path.exists() {
if self.is_proper(&path) {
return path.join(&self.app_name).join("config");
}
return path.join(&self.app_name);
}
self.home.join(".config").join(&self.app_name)
}
fn get_data_home(&self) -> Utf8PathBuf {
let default = self.home.join("Library").join("Application Support");
let path: Utf8PathBuf = EnvVal::from("XDG_DATA_HOME")
.with_default_value(&default)
.into();
if path.exists() {
if self.is_proper(&path) {
return path.join(&self.app_name).join("data");
}
return path.join(&self.app_name);
}
self.home.join(".local").join("share").join(&self.app_name)
}
fn get_log_home(&self) -> Utf8PathBuf {
let default = self.home.join("Library").join("Logs");
let app_name = self.app_name.to_uppercase();
let env_var_name = format!("{}_LOG_DIR", &app_name);
let path: Utf8PathBuf = EnvVal::from(&env_var_name)
.with_default_value(&default)
.into();
if path == default {
return path.join(&self.app_name);
}
if self.is_proper(&path) {
return path.join(&self.app_name).join("log");
}
self.home.join(".local").join("log").join(&self.app_name)
}
fn get_state_home(&self) -> Utf8PathBuf {
let default = self.home.join("Library").join("Application Support");
let path: Utf8PathBuf = EnvVal::from("XDG_STATE_HOME")
.with_default_value(&default)
.into();
if path.exists() {
if self.is_proper(&path) {
return path.join(&self.app_name).join("state");
}
return path.join(&self.app_name);
}
self.home.join(".local").join("state").join(&self.app_name)
}
}