use std::path::{Path, PathBuf};
use crate::constants::CHROOTS;
use crate::error::Result;
use crate::scope::validate_chroot_name;
const APP: &str = "unifier";
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UnifierHome {
global: PathBuf,
effective: PathBuf,
chroot: Option<String>,
}
impl UnifierHome {
pub fn resolve(explicit: Option<PathBuf>, chroot: Option<String>) -> Result<Self> {
let global = resolve_global(explicit)?;
let effective = match &chroot {
Some(name) => {
validate_chroot_name(name)?;
global.join(CHROOTS).join(name)
}
None => global.clone(),
};
Ok(Self {
global,
effective,
chroot,
})
}
pub fn path(&self) -> &Path {
&self.effective
}
pub fn global_path(&self) -> &Path {
&self.global
}
pub fn chroot_name(&self) -> Option<&str> {
self.chroot.as_deref()
}
pub fn ensure(&self) -> Result<()> {
std::fs::create_dir_all(self.path())?;
Ok(())
}
}
fn resolve_global(explicit: Option<PathBuf>) -> Result<PathBuf> {
if let Some(p) = explicit {
return Ok(p);
}
if let Ok(p) = std::env::var("UNIFIER_HOME") {
return Ok(PathBuf::from(p));
}
let base = user_home()?.join(".local");
Ok(base.join(APP))
}
fn user_home() -> Result<PathBuf> {
std::env::var_os("HOME")
.or_else(|| std::env::var_os("USERPROFILE"))
.map(PathBuf::from)
.ok_or_else(|| crate::Error::msg("could not resolve home directory"))
}