use anyhow::{anyhow, Context};
use directories::{BaseDirs, ProjectDirs};
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct Paths {
pub base: BaseDirs,
pub project: ProjectDirs,
pub core: mcvm_core::Paths,
pub data: PathBuf,
pub internal: PathBuf,
pub addons: PathBuf,
pub pkg_cache: PathBuf,
pub pkg_index_cache: PathBuf,
pub logs: PathBuf,
pub launch_logs: PathBuf,
pub run: PathBuf,
pub snapshots: PathBuf,
pub proxy: PathBuf,
pub plugins: PathBuf,
}
impl Paths {
pub async fn new() -> anyhow::Result<Paths> {
let out = Self::new_no_create()?;
out.create_dirs().await?;
Ok(out)
}
pub async fn create_dirs(&self) -> anyhow::Result<()> {
let _ = tokio::join!(
tokio::fs::create_dir_all(&self.data),
tokio::fs::create_dir_all(self.project.cache_dir()),
tokio::fs::create_dir_all(self.project.config_dir()),
tokio::fs::create_dir_all(&self.internal),
tokio::fs::create_dir_all(&self.addons),
tokio::fs::create_dir_all(&self.pkg_cache),
tokio::fs::create_dir_all(&self.pkg_index_cache),
tokio::fs::create_dir_all(&self.logs),
tokio::fs::create_dir_all(&self.launch_logs),
tokio::fs::create_dir_all(&self.run),
tokio::fs::create_dir_all(&self.snapshots),
tokio::fs::create_dir_all(&self.proxy),
tokio::fs::create_dir_all(&self.plugins),
);
self.core.create_dirs()?;
Ok(())
}
pub fn new_no_create() -> anyhow::Result<Self> {
let base = BaseDirs::new().ok_or(anyhow!("Base directories failed"))?;
let project =
ProjectDirs::from("", "mcvm", "mcvm").ok_or(anyhow!("Base directories failed"))?;
let data = project.data_dir().to_owned();
let internal = data.join("internal");
let addons = internal.join("addons");
let pkg_cache = project.cache_dir().join("pkg");
let pkg_index_cache = pkg_cache.join("index");
let logs = data.join("logs");
let launch_logs = logs.join("launch");
let run = project
.runtime_dir()
.map(|x| x.to_path_buf())
.unwrap_or(internal.join("run"));
let snapshots = internal.join("snapshots");
let proxy = data.join("proxy");
let plugins = data.join("plugins");
let core_paths = mcvm_core::Paths::new().context("Failed to create core paths")?;
Ok(Paths {
base,
project,
core: core_paths,
data,
internal,
addons,
pkg_cache,
pkg_index_cache,
logs,
launch_logs,
run,
snapshots,
proxy,
plugins,
})
}
}