OneLauncher-Cracked/packages/core/src/store/dirs.rs
2025-04-11 16:06:03 +02:00

89 lines
No EOL
2.3 KiB
Rust

use std::path::PathBuf;
use tokio::sync::OnceCell;
use crate::{utils, LauncherResult};
use super::Core;
/// The static [`OnceCell<RwLock<Dirs>>`] for storing the global directory state.
/// Should be initialized as soon as possible (preferably before logging)
static DIRS_GLOBAL: OnceCell<Dirs> = OnceCell::const_new();
pub struct Dirs {
base_dir: PathBuf,
}
#[derive(Debug, thiserror::Error)]
pub enum DirectoryError {
#[error("Failed to get the base directory for the launcher.")]
BaseDir,
}
impl Dirs {
pub async fn get() -> LauncherResult<&'static Self> {
DIRS_GLOBAL.get_or_try_init(async || {
Self::initialize()
}).await
}
fn initialize() -> LauncherResult<Self> {
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
}
}
macro_rules! dirs_impl {
($($name:ident => |$self:ident| $path:expr),*$(,)?) => {
paste::paste! {
impl Dirs {
$(
#[must_use]
pub fn $name(&self) -> PathBuf {
let $self = self;
$path
}
pub async fn [<get _ $name>]() -> LauncherResult<PathBuf> {
Dirs::get().await.map(|$self| {
$self.$name()
})
}
)*
}
}
};
}
dirs_impl! {
db_file => |this| this.base_dir.join("user_data.db"),
settings_file => |this| this.base_dir.join("settings.json"),
auth_file => |this| this.base_dir.join("auth.json"),
launcher_logs_dir => |this| this.base_dir.join("logs"),
clusters_dir => |this| this.base_dir.join("clusters"),
metadata_dir => |this| this.base_dir.join("metadata"),
versions_dir => |this| this.metadata_dir().join("versions"),
libraries_dir => |this| this.metadata_dir().join("libraries"),
natives_dir => |this| this.metadata_dir().join("natives"),
java_dir => |this| this.metadata_dir().join("java"),
caches_dir => |this| this.metadata_dir().join("caches"),
assets_dir => |this| this.metadata_dir().join("assets"),
legacy_assets_dir => |this| this.metadata_dir().join("resources"),
assets_index_dir => |this| this.assets_dir().join("indexes"),
assets_object_dir => |this| this.assets_dir().join("objects"),
}