use std::path::PathBuf; use tokio::sync::OnceCell; use crate::{utils, LauncherResult}; use super::Core; /// The static [`OnceCell>`] for storing the global directory state. /// Should be initialized as soon as possible (preferably before logging) static DIRS_GLOBAL: OnceCell = OnceCell::const_new(); pub struct Dirs { base_dir: PathBuf, } impl Dirs { pub async fn get() -> LauncherResult<&'static Self> { DIRS_GLOBAL.get_or_try_init(async || { Self::initialize() }).await } fn initialize() -> LauncherResult { let base_dir = utils::io::env_path("LAUNCHER_DIR") .or_else(|| Some(dirs::data_dir()?.join(Core::get().launcher_name.clone()))) .ok_or(DirectoryError::BaseDir)?; Ok(Self { base_dir }) } /// Get the base directory for the launcher. #[must_use] pub const fn base_dir(&self) -> &PathBuf { &self.base_dir } /// Get the launcher's logs directory. #[must_use] pub fn launcher_logs_dir(&self) -> PathBuf { self.base_dir().join("logs") } // --- FILES --- #[must_use] pub fn db_file(&self) -> PathBuf { self.base_dir().join("user_data.db") } #[must_use] pub fn settings_file(&self) -> PathBuf { self.base_dir().join("settings.json") } // --- GAME DIRECTORIES --- /// Get the `config_dir/clusters` folder for the clusters. #[must_use] pub fn clusters_dir(&self) -> PathBuf { self.base_dir().join("clusters") } /// Get the `config_dir/metadata` folder within the core config directory. #[inline] #[must_use] pub fn metadata_dir(&self) -> PathBuf { self.base_dir().join("metadata") } /// Get the `config_dir/metadata/libraries` folder for Minecraft libraries. #[must_use] pub fn libraries_dir(&self) -> PathBuf { self.metadata_dir().join("libraries") } /// Get the `config_dir/metadata/natives` folder for Minecraft natives. #[must_use] pub fn natives_dir(&self) -> PathBuf { self.metadata_dir().join("natives") } /// Get the `config_dir/metadata/java` directory. #[must_use] pub fn java_dir(&self) -> PathBuf { self.metadata_dir().join("java") } /// Get the `config_dir/metadata/caches` directory. #[must_use] pub fn caches_dir(&self) -> PathBuf { self.metadata_dir().join("caches") } } #[derive(Debug, thiserror::Error)] pub enum DirectoryError { #[error("Failed to get the base directory for the launcher.")] BaseDir, }