feat: groundwork for multi-profile support

This commit is contained in:
2025-03-03 02:07:15 +01:00
parent d25841853c
commit 6410ca2721
16 changed files with 744 additions and 184 deletions

View File

@ -1,16 +1,64 @@
use std::hash::{DefaultHasher, Hash, Hasher};
use crate::pkg::PkgKey;
use crate::{model::misc::Game, pkg::PkgKey};
use crate::pkg_store::PackageStore;
use crate::Profile;
use crate::{util, Profile};
use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
use tauri::AppHandle;
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct GlobalConfig {
pub recent_profile: Option<(Game, String)>
}
pub struct AppData {
pub profile: Option<Profile>,
pub pkgs: PackageStore,
pub cfg: GlobalConfig
}
impl AppData {
pub fn new(app: AppHandle) -> AppData {
let path = util::get_dirs()
.config_dir()
.join("config.json");
let cfg = std::fs::read_to_string(&path)
.and_then(|s| Ok(serde_json::from_str::<GlobalConfig>(&s)?))
.unwrap_or_default();
let profile = match cfg.recent_profile {
Some((ref game, ref name)) => Profile::load(game, name).ok(),
None => None
};
AppData {
profile,
pkgs: PackageStore::new(app),
cfg
}
}
pub fn write(&self) -> Result<(), std::io::Error> {
let path = util::get_dirs()
.config_dir()
.join("config.json");
std::fs::write(&path, serde_json::to_string(&self.cfg)?)
}
pub fn switch_profile(&mut self, game: &Game, name: &str) -> Result<()> {
self.profile = Profile::load(game, name).ok();
if self.profile.is_some() {
self.cfg.recent_profile = Some((game.to_owned(), name.to_owned()));
} else {
self.cfg.recent_profile = None;
}
self.write()?;
Ok(())
}
pub fn toggle_package(&mut self, key: PkgKey, enable: bool) -> Result<()> {
log::debug!("toggle: {} {}", key, enable);
@ -22,12 +70,12 @@ impl AppData {
let loc = pkg.loc
.clone()
.ok_or_else(|| anyhow!("Attempted to enable a non-existent package"))?;
profile.mods.insert(key);
profile.data.mods.insert(key);
for d in &loc.dependencies {
_ = self.toggle_package(d.clone(), true);
}
} else {
profile.mods.remove(&key);
profile.data.mods.remove(&key);
for (ckey, pkg) in self.pkgs.get_all() {
if let Some(loc) = pkg.loc {
if loc.dependencies.contains(&key) {
@ -42,7 +90,7 @@ impl AppData {
pub fn sum_packages(&self, p: &Profile) -> String {
let mut hasher = DefaultHasher::new();
for pkg in &p.mods {
for pkg in &p.data.mods {
let x = self.pkgs.get(pkg).unwrap().loc.as_ref().unwrap();
pkg.hash(&mut hasher);
x.version.hash(&mut hasher);