use super::{ConfigDirectory, ModuleDirectory, ProgramDirectory};
use alloc::format;
use camino::Utf8PathBuf;
use derive_more::Display;
use std::{
io::{Error, ErrorKind, Result},
path::Path,
};
#[derive(Debug, Display)]
#[display("StateDirectory({:?})", path)]
pub struct StateDirectory {
path: Utf8PathBuf,
}
impl StateDirectory {
pub fn home() -> Result<Self> {
let home_dir = std::env::home_dir().expect("home directory not found"); Self::open(home_dir.join(".asimov"))
}
pub fn open(path: impl AsRef<Path>) -> Result<Self> {
let path = path.as_ref();
if !path.exists() {
std::fs::create_dir_all(path)?;
}
let path = Utf8PathBuf::from_path_buf(path.to_path_buf()).map_err(|e| {
Error::new(
ErrorKind::InvalidFilename,
format!("failed to open non-UTF-8 path: {}", e.display()),
)
})?;
Ok(StateDirectory { path })
}
pub fn configs(&self) -> Result<ConfigDirectory> {
ConfigDirectory::open(self.path.join("configs"))
}
pub fn modules(&self) -> Result<ModuleDirectory> {
ModuleDirectory::open(self.path.join("modules"))
}
pub fn programs(&self) -> Result<ProgramDirectory> {
ProgramDirectory::open(self.path.join("libexec"))
}
pub fn as_str(&self) -> &str {
self.path.as_str()
}
}
impl AsRef<str> for StateDirectory {
fn as_ref(&self) -> &str {
self.path.as_str()
}
}
impl AsRef<Path> for StateDirectory {
fn as_ref(&self) -> &Path {
self.path.as_std_path()
}
}
#[cfg(feature = "camino")]
impl AsRef<Utf8Path> for StateDirectory {
fn as_ref(&self) -> &Utf8Path {
self.path.as_path()
}
}
impl crate::StateDirectory for StateDirectory {
fn has_configs(&self) -> bool {
self.path.join("configs").exists()
}
fn has_modules(&self) -> bool {
self.path.join("modules").exists()
}
fn has_programs(&self) -> bool {
self.path.join("libexec").exists()
}
}