use std::hash::{DefaultHasher, Hash, Hasher}; use crate::{model::misc::Game, pkg::PkgKey}; use crate::pkg_store::PackageStore; 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, pub pkgs: PackageStore, pub cfg: GlobalConfig, } impl AppData { pub fn new(apph: AppHandle) -> AppData { let cfg = std::fs::read_to_string(util::config_dir().join("config.json")) .and_then(|s| Ok(serde_json::from_str::(&s)?)) .unwrap_or_default(); let profile = match cfg.recent_profile { Some((ref game, ref name)) => Profile::load(game.clone(), name.clone()).ok(), None => None }; AppData { profile, pkgs: PackageStore::new(apph.clone()), cfg, } } pub fn write(&self) -> Result<(), std::io::Error> { std::fs::write(util::config_dir().join("config.json"), serde_json::to_string(&self.cfg)?) } pub fn switch_profile(&mut self, game: Game, name: String) -> Result<()> { match Profile::load(game.clone(), name.clone()) { Ok(profile) => { self.profile = Some(profile); self.cfg.recent_profile = Some((game, name)); self.write()?; Ok(()) } Err(e) => { self.profile = None; self.cfg.recent_profile = None; Err(e) } } } pub fn toggle_package(&mut self, key: PkgKey, enable: bool) -> Result<()> { log::debug!("toggle: {} {}", key, enable); let profile = self.profile.as_mut().ok_or_else(|| anyhow!("No profile"))?; if enable { let pkg = self.pkgs.get(&key)?; let loc = pkg.loc .clone() .ok_or_else(|| anyhow!("Attempted to enable a non-existent package"))?; profile.data.mods.insert(key); for d in &loc.dependencies { _ = self.toggle_package(d.clone(), true); } } else { profile.data.mods.remove(&key); for (ckey, pkg) in self.pkgs.get_all() { if let Some(loc) = pkg.loc { if loc.dependencies.contains(&key) { self.toggle_package(ckey, false)?; } } } } Ok(()) } pub fn sum_packages(&self, p: &Profile) -> String { let mut hasher = DefaultHasher::new(); 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); } hasher.finish().to_string() } }