diff --git a/rust/src/cmd.rs b/rust/src/cmd.rs index 982dc52..0fe6b7c 100644 --- a/rust/src/cmd.rs +++ b/rust/src/cmd.rs @@ -1,4 +1,3 @@ -use ini::Ini; use log; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::path::PathBuf; @@ -66,7 +65,7 @@ pub async fn startline(app: AppHandle, refresh: bool) -> Result<(), String> { let mut amd_dlls = Vec::new(); if let Some(p) = &appd.profile { hash = appd.sum_packages(p); - (game_dlls, amd_dlls) = prepare_dlls(p.meta.game, p.mod_pkgs(), &appd.pkgs).map_err(|e| e.to_string())? + (game_dlls, amd_dlls) = prepare_dlls(p.meta.game, p.mod_pkgs(), &appd.pkgs); } if let Some(p) = &appd.profile { log::debug!("{}", hash); @@ -74,13 +73,12 @@ pub async fn startline(app: AppHandle, refresh: bool) -> Result<(), String> { let patches_enabled = appd.patches_enabled( &p.data.sgt.target, &p.data.sgt.target.parent().unwrap().join("amdaemon.exe") - ).map_err(|e| e.to_string())?; + ).map_err(|e| format!("Unable to apply patches: {e}"))?; #[cfg(target_os = "windows")] let info = p.prepare_display() - .map_err(|e| e.to_string())?; - let lineup_res = p.line_up(hash, refresh, patches_enabled).await - .map_err(|e| e.to_string()); + .map_err(|e| format!("Unable to configure displays: {e}"))?; + let lineup_res = p.line_up(hash, refresh, patches_enabled).await; #[cfg(target_os = "windows")] if let Some(info) = info { @@ -88,11 +86,12 @@ pub async fn startline(app: AppHandle, refresh: bool) -> Result<(), String> { if lineup_res.is_ok() { Display::wait_for_exit(app.clone(), info); } else { - Display::clean_up(&info).map_err(|e| e.to_string())?; + Display::clean_up(&info) + .map_err(|e| format!("Unable to restore displays: {e}"))?; } } - lineup_res?; + lineup_res.map_err(|e| format!("Init failed: {e}"))?; let app_clone = app.clone(); let p_clone = p.clone(); @@ -133,7 +132,7 @@ pub async fn install_package( let mut appd = state.lock().await; appd.pkgs.install_package(&key, force, true, enable) .await - .map_err(|e| e.to_string()) + .map_err(|e| format!("Unable to install {key}: {e}")) } #[tauri::command] @@ -143,10 +142,10 @@ pub async fn delete_package(state: State<'_, tokio::sync::Mutex>, key: let mut appd = state.lock().await; appd.pkgs.delete_package(&key, true) .await - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Unable to delete {key}: {e}"))?; - appd.toggle_package(key, ToggleAction::Disable) - .map_err(|e| e.to_string()) + appd.toggle_package(key.clone(), ToggleAction::Disable) + .map_err(|e| format!("Unable to disable {key}: {e}")) } #[tauri::command] @@ -155,7 +154,7 @@ pub async fn get_package(state: State<'_, tokio::sync::Mutex>, key: Pkg let appd = state.lock().await; appd.pkgs.get(&key) - .map_err(|e| e.to_string()) + .map_err(|e| format!("Unable to load {key}: {e}")) .cloned() } @@ -164,8 +163,8 @@ pub async fn toggle_package(state: State<'_, tokio::sync::Mutex>, key: log::debug!("invoke: toggle_package({}, {})", key, enable); let mut appd = state.lock().await; - appd.toggle_package(key, if enable { ToggleAction::EnableRecursive } else { ToggleAction::Disable }) - .map_err(|e| e.to_string()) + appd.toggle_package(key.clone(), if enable { ToggleAction::EnableRecursive } else { ToggleAction::Disable }) + .map_err(|e| format!("Unable to toggle {key}: {e}")) } #[tauri::command] @@ -220,9 +219,12 @@ pub async fn create_package( games: Some(games) }; - std::fs::create_dir(&dir).map_err(|e| e.to_string())?; - let json = serde_json::to_string_pretty(&manifest).map_err(|e| e.to_string())?; - std::fs::write(dir.join("manifest.json"), json).map_err(|e| e.to_string())?; + std::fs::create_dir(&dir) + .map_err(|e| format!("Unable to create {} directory: {e}", dir.file_name().unwrap_or_default().to_string_lossy()))?; + let json = serde_json::to_string_pretty(&manifest) + .map_err(|e| format!("Unable to serialize manifest.json: {e}"))?; + std::fs::write(dir.join("manifest.json"), json) + .map_err(|e| format!("Unable to write manifest.json: {e}"))?; Ok(()) } @@ -234,7 +236,7 @@ pub async fn reload_all_packages(state: State<'_, tokio::sync::Mutex>) let mut appd = state.lock().await; appd.pkgs.reload_all() .await - .map_err(|e| e.to_string()) + .map_err(|e| format!("Unable to reload packages: {e}")) } #[tauri::command] @@ -288,17 +290,17 @@ pub async fn fetch_listings(state: State<'_, Mutex>) -> Result<(), Stri // Can be this lazy for now as there are only two short lists let listings1 = PackageStore::fetch_listings(Game::Ongeki).await - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Unable to fetch Chunithm listings: {e}"))?; let listings2 = PackageStore::fetch_listings(Game::Chunithm).await - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Unable to fetch Ongeki listings: {e}"))?; let mut appd = state.lock().await; appd.pkgs.process_fetched_listings(listings1, Game::Ongeki); appd.pkgs.process_fetched_listings(listings2, Game::Chunithm); appd.pkgs.save().await - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Unable to save package-list: {e}"))?; Ok(()) } @@ -307,7 +309,9 @@ pub async fn fetch_listings(state: State<'_, Mutex>) -> Result<(), Stri pub async fn list_profiles() -> Result, String> { log::debug!("invoke: list_profiles"); - let list = crate::profiles::list_profiles().await.map_err(|e| e.to_string())?; + let list = crate::profiles::list_profiles() + .await + .map_err(|e| format!("Unable to list profiles: {e}"))?; Ok(list) } @@ -321,7 +325,7 @@ pub async fn init_profile( let mut appd = state.lock().await; let new_profile = Profile::new(ProfileMeta { game, name }) - .map_err(|e| format!("Unable to create profile: {}", e))?; + .map_err(|e| format!("Unable to create a profile: {}", e))?; appd.profile = Some(new_profile); @@ -333,7 +337,8 @@ pub async fn load_profile(state: State<'_, Mutex>, game: Game, name: St log::debug!("invoke: load_profile({} {:?})", game, name); let mut appd = state.lock().await; - appd.switch_profile(game, name).map_err(|e| e.to_string())?; + appd.switch_profile(game, name) + .map_err(|e| format!("Unable to switch profile: {e}"))?; appd.fix(); Ok(()) } @@ -440,7 +445,7 @@ pub async fn save_current_profile(state: State<'_, Mutex>) -> Result<() appd.fix(); match &mut appd.profile { Some(p) => { - p.save().map_err(|e| e.to_string()) + p.save().map_err(|e| format!("Unable to save profile: {e}")) }, None => { Err("no profile to save".to_owned()) @@ -454,16 +459,7 @@ pub async fn load_segatools_ini(state: State<'_, Mutex>, path: PathBuf) let mut appd = state.lock().await; if let Some(p) = &mut appd.profile { - let str = std::fs::read_to_string(path).map_err(|e| e.to_string())?; - // Stupid path escape hack for the ini reader - let str = str.replace("\\", "\\\\").replace("\\\\\\\\", "\\\\"); - let ini = Ini::load_from_str(&str).map_err(|e| e.to_string())?; - p.data.sgt.load_from_ini(&ini, p.config_dir()).map_err(|e| e.to_string())?; - p.data.network.load_from_ini(&ini).map_err(|e| e.to_string())?; - if let Some(kb) = &mut p.data.keyboard { - kb.load_from_ini(&ini).map_err(|e| e.to_string())?; - } - p.save().map_err(|e| e.to_string())?; + p.load_segatools_ini(path).map_err(|e| format!("Unable to load segatools.ini: {e}"))?; } Ok(()) @@ -474,7 +470,8 @@ pub async fn create_shortcut(_app: AppHandle, profile_meta: ProfileMeta) -> Resu log::debug!("invoke: create_shortcut({:?})", profile_meta); #[cfg(target_os = "windows")] - return util::create_shortcut(_app, &profile_meta).map_err(|e| e.to_string()); + return util::create_shortcut(_app, &profile_meta) + .map_err(|e| format!("Unable to create a shortcut: {e}")); #[cfg(not(target_os = "windows"))] return Err("unsupported".to_owned()); @@ -493,7 +490,7 @@ pub async fn export_profile( match &appd.profile { Some(p) => { p.export(export_keychip, files, is_diagnostic) - .map_err(|e| e.to_string())?; + .map_err(|e| format!("Unable to export profile: {e}"))?; } None => { let err = "export_profile: no profile".to_owned(); @@ -509,7 +506,7 @@ pub async fn export_profile( pub async fn import_profile(path: PathBuf) -> Result<(), String> { log::debug!("invoke: import_profile({:?})", path); - Profile::import(path).map_err(|e| e.to_string()) + Profile::import(path).map_err(|e| format!("Unable to import profile: {e}")) } #[tauri::command] @@ -521,11 +518,13 @@ pub async fn clear_cache(state: State<'_, Mutex>) -> Result<(), String> let dir = p.data_dir().join("mu3-mods-cache"); let path = dir.join("data_cache.bin"); if path.exists() { - std::fs::remove_file(path).map_err(|e| e.to_string())?; + std::fs::remove_file(path) + .map_err(|e| format!("Unable to delete data_cache: {e}"))?; } let path = dir.join("data_fumen_analysis_cache.bin"); if path.exists() { - std::fs::remove_file(path).map_err(|e| e.to_string())?; + std::fs::remove_file(path) + .map_err(|e| format!("Unable to delete data_fumen_analysis_cache: {e}"))?; } } @@ -565,7 +564,7 @@ pub async fn set_global_config(state: State<'_, Mutex>, field: GlobalCo GlobalConfigField::EnableAutoupdates => appd.cfg.enable_autoupdates = value, GlobalConfigField::Verbose => appd.cfg.verbose = value, }; - appd.write().map_err(|e| e.to_string()) + appd.write().map_err(|e| format!("Unable to write config.json: {e}")) } #[tauri::command] @@ -613,7 +612,7 @@ pub async fn file_exists(path: String) -> Result { // Easier than trying to get the barely-documented tauri permissions system to work #[tauri::command] pub async fn open_file(path: String) -> Result<(), String> { - open::that(path).map_err(|e| e.to_string())?; + open::that(&path).map_err(|e| format!("Unable to open {path}: {e}"))?; Ok(()) } @@ -638,12 +637,14 @@ pub async fn list_com_ports() -> Result, String> { } #[tauri::command] -pub async fn list_patches(state: State<'_, Mutex>, target: String) -> Result, String> { - log::debug!("invoke: list_patches({})", target); +pub async fn list_patches(state: State<'_, Mutex>, target: PathBuf) -> Result, String> { + log::debug!("invoke: list_patches({:?})", target); let mut appd = state.lock().await; appd.fix(); - let list = appd.patch_vec.find_patches(target).map_err(|e| e.to_string())?; + let list = appd.patch_vec + .find_patches(&target) + .map_err(|e| format!("Unable to list patches for {}: {e}", target.file_name().unwrap_or_default().to_string_lossy()))?; Ok(list) } \ No newline at end of file diff --git a/rust/src/modules/display_windows.rs b/rust/src/modules/display_windows.rs index 73dd57d..43294cb 100644 --- a/rust/src/modules/display_windows.rs +++ b/rust/src/modules/display_windows.rs @@ -103,7 +103,10 @@ impl Display { } display_set.apply().map_err( - |_| anyhow!("The selected monitor has been disconnected or doesn't support the chosen display mode") + |e| { + log::error!("display_set: {e}"); + anyhow!("The selected monitor has been disconnected or doesn't support the chosen display mode") + } )?; displayz::refresh()?; diff --git a/rust/src/modules/package.rs b/rust/src/modules/package.rs index 94d90fc..40afdbf 100644 --- a/rust/src/modules/package.rs +++ b/rust/src/modules/package.rs @@ -72,7 +72,7 @@ pub fn prepare_dlls( game: Game, enabled_pkgs: &BTreeSet, store: &PackageStore, -) -> Result<(Vec, Vec)> { +) -> (Vec, Vec) { let mut res_game = Vec::new(); let mut res_amd = Vec::new(); for pkg in enabled_pkgs { @@ -99,5 +99,5 @@ pub fn prepare_dlls( } } } - Ok((res_game, res_amd)) + (res_game, res_amd) } \ No newline at end of file diff --git a/rust/src/profiles/mod.rs b/rust/src/profiles/mod.rs index db5e10d..3d0c8d6 100644 --- a/rust/src/profiles/mod.rs +++ b/rust/src/profiles/mod.rs @@ -479,6 +479,21 @@ impl Profile { } Ok(()) } + + pub fn load_segatools_ini(&mut self, path: impl AsRef) -> Result<()> { + let str = std::fs::read_to_string(path.as_ref())?; + // Stupid path escape hack for the ini reader + let str = str.replace("\\", "\\\\").replace("\\\\\\\\", "\\\\"); + let ini = ini::Ini::load_from_str(&str)?; + self.data.sgt.load_from_ini(&ini, self.config_dir())?; + self.data.network.load_from_ini(&ini)?; + if let Some(kb) = &mut self.data.keyboard { + kb.load_from_ini(&ini)?; + } + self.save()?; + + Ok(()) + } } impl ProfilePaths for Profile {