forked from didirus/AstralRinth
Initial draft of profile metadata format & CLI (#17)
* Initial draft of profile metadata format * Remove records, add Clippy to Nix, fix Clippy error * Work on profile definition * BREAKING: Make global settings consistent with profile settings * Add builder methods & format * Integrate launching with profiles * Add profile loading * Launching via profile, API tweaks, and yak shaving * Incremental update, committing everything due to personal system maintainance * Prepare for review cycle * Remove reminents of experimental work * CLI: allow people to override the non-empty directory check * Fix mistake in previous commit * Handle trailing whitespace and newlines in prompts * Revamp prompt to use dialoguer and support defaults * Make requested changes
This commit is contained in:
@@ -1,33 +1,51 @@
|
||||
use std::path::Path;
|
||||
use super::profiles::*;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::{data::DataError, LAUNCHER_WORK_DIR};
|
||||
use once_cell::sync;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
const SETTINGS_FILE: &str = "settings.json";
|
||||
const ICONS_PATH: &str = "icons";
|
||||
const METADATA_DIR: &str = "meta";
|
||||
|
||||
static SETTINGS: sync::OnceCell<RwLock<Settings>> = sync::OnceCell::new();
|
||||
pub const FORMAT_VERSION: u32 = 1;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
#[serde(default)]
|
||||
pub struct Settings {
|
||||
pub memory: i32,
|
||||
pub game_resolution: (i32, i32),
|
||||
pub custom_java_args: String,
|
||||
pub java_8_path: Option<String>,
|
||||
pub java_17_path: Option<String>,
|
||||
pub wrapper_command: Option<String>,
|
||||
pub memory: MemorySettings,
|
||||
pub game_resolution: WindowSize,
|
||||
pub custom_java_args: Vec<String>,
|
||||
pub java_8_path: Option<PathBuf>,
|
||||
pub java_17_path: Option<PathBuf>,
|
||||
pub hooks: ProfileHooks,
|
||||
pub icon_path: PathBuf,
|
||||
pub metadata_dir: PathBuf,
|
||||
pub profiles: HashSet<PathBuf>,
|
||||
pub max_concurrent_downloads: usize,
|
||||
pub version: u32,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
memory: 2048,
|
||||
game_resolution: (854, 480),
|
||||
custom_java_args: "".to_string(),
|
||||
memory: MemorySettings::default(),
|
||||
game_resolution: WindowSize::default(),
|
||||
custom_java_args: Vec::new(),
|
||||
java_8_path: None,
|
||||
java_17_path: None,
|
||||
wrapper_command: None,
|
||||
hooks: ProfileHooks::default(),
|
||||
icon_path: Path::new(LAUNCHER_WORK_DIR).join(ICONS_PATH),
|
||||
metadata_dir: Path::new(LAUNCHER_WORK_DIR).join(METADATA_DIR),
|
||||
profiles: HashSet::new(),
|
||||
max_concurrent_downloads: 32,
|
||||
version: FORMAT_VERSION,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,10 +68,14 @@ impl Settings {
|
||||
if SETTINGS.get().is_none() {
|
||||
let new = Self::default();
|
||||
|
||||
std::fs::write(
|
||||
tokio::fs::rename(SETTINGS_FILE, format!("{SETTINGS_FILE}.bak"))
|
||||
.await?;
|
||||
|
||||
tokio::fs::write(
|
||||
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE),
|
||||
&serde_json::to_string(&new)?,
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
|
||||
SETTINGS.get_or_init(|| RwLock::new(new));
|
||||
}
|
||||
@@ -66,7 +88,7 @@ impl Settings {
|
||||
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE),
|
||||
)?)?;
|
||||
|
||||
let write = &mut *SETTINGS
|
||||
let mut write = SETTINGS
|
||||
.get()
|
||||
.ok_or_else(|| DataError::InitializedError("settings".to_string()))?
|
||||
.write()
|
||||
@@ -82,17 +104,24 @@ impl Settings {
|
||||
|
||||
std::fs::write(
|
||||
Path::new(LAUNCHER_WORK_DIR).join(SETTINGS_FILE),
|
||||
&serde_json::to_string(&*settings)?,
|
||||
&serde_json::to_string_pretty(&*settings)?,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get<'a>() -> Result<RwLockReadGuard<'a, Self>, DataError> {
|
||||
Ok(SETTINGS
|
||||
Ok(Self::get_or_uninit::<'a>()?.read().await)
|
||||
}
|
||||
|
||||
pub async fn get_mut<'a>() -> Result<RwLockWriteGuard<'a, Self>, DataError>
|
||||
{
|
||||
Ok(Self::get_or_uninit::<'a>()?.write().await)
|
||||
}
|
||||
|
||||
fn get_or_uninit<'a>() -> Result<&'a RwLock<Self>, DataError> {
|
||||
SETTINGS
|
||||
.get()
|
||||
.ok_or_else(|| DataError::InitializedError("settings".to_string()))?
|
||||
.read()
|
||||
.await)
|
||||
.ok_or_else(|| DataError::InitializedError("settings".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user