From 3a892043c4cdedcf5a509a63dedad0e9de15bd57 Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:30:17 +0800 Subject: [PATCH] refactor(backup): share restore finalize path restore_webdav_backup and restore_local_backup duplicated the credential extraction (backup creation strips the WebDAV credentials, so both re-inject the live ones), the archive extraction and the finalize tail. Move that tail into a private restore_backup_archive helper so the two entries keep only their download/locate logic; the config-write lock scope and the off-runtime extraction land in one place. The webdav entry keeps its downloaded-file cleanup. --- src-tauri/src/feat/backup.rs | 73 ++++++++++++++---------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/src-tauri/src/feat/backup.rs b/src-tauri/src/feat/backup.rs index 802b37bae..8f81ef55c 100644 --- a/src-tauri/src/feat/backup.rs +++ b/src-tauri/src/feat/backup.rs @@ -136,14 +136,35 @@ pub async fn delete_webdav_backup(filename: String) -> Result<()> { }) } +/// Backup creation strips the WebDAV credentials, so the live ones are kept. +async fn restore_backup_archive(path: PathBuf) -> Result<()> { + let (webdav_url, webdav_username, webdav_password) = { + let verge = Config::verge().await; + let verge = verge.latest_arc(); + ( + verge.webdav_url.clone(), + verge.webdav_username.clone(), + verge.webdav_password.clone(), + ) + }; + + let home_dir = app_home_dir()?; + AsyncHandler::spawn_blocking(move || -> Result<()> { + let file = std::fs::File::open(&path)?; + let mut zip = zip::ZipArchive::new(file)?; + zip.extract(&home_dir)?; + Ok(()) + }) + .await + .map_err(|join| anyhow!("backup extraction task failed: {join}"))??; + + // Held for the config-data transition only; extraction is plain filesystem work. + let _profile_write = crate::config::profiles::PROFILE_WRITE_LOCK.lock().await; + finalize_restored_verge_config(webdav_url, webdav_username, webdav_password).await +} + #[tracing::instrument(skip_all, level = "info", fields(filename = %filename))] pub async fn restore_webdav_backup(filename: String) -> Result<()> { - let verge = Config::verge().await; - let verge_data = verge.latest_arc(); - let webdav_url = verge_data.webdav_url.clone(); - let webdav_username = verge_data.webdav_username.clone(); - let webdav_password = verge_data.webdav_password.clone(); - let backup_storage_path = app_home_dir() .map_err(|e| anyhow::anyhow!("Failed to get app home dir: {e}"))? .join(filename.as_str()); @@ -160,20 +181,7 @@ pub async fn restore_webdav_backup(filename: String) -> Result<()> { err })?; - let value = backup_storage_path.clone(); - let home_dir = app_home_dir()?; - AsyncHandler::spawn_blocking(move || -> Result<()> { - let file = std::fs::File::open(&value)?; - let mut zip = zip::ZipArchive::new(file)?; - zip.extract(&home_dir)?; - Ok(()) - }) - .await - .map_err(|join| anyhow!("backup extraction task failed: {join}"))??; - - // Held for the config-data transition only; extraction is plain filesystem work. - let _profile_write = crate::config::profiles::PROFILE_WRITE_LOCK.lock().await; - let res = finalize_restored_verge_config(webdav_url, webdav_username, webdav_password).await; + let res = restore_backup_archive(backup_storage_path.clone()).await; let _ = backup_storage_path.remove_if_exists().await; res } @@ -342,30 +350,7 @@ pub async fn restore_local_backup(filename: String) -> Result<()> { return Err(anyhow!("Backup file not found: {}", filename)); } - let (webdav_url, webdav_username, webdav_password) = { - let verge = Config::verge().await; - let verge = verge.latest_arc(); - ( - verge.webdav_url.clone(), - verge.webdav_username.clone(), - verge.webdav_password.clone(), - ) - }; - - let home_dir = app_home_dir()?; - AsyncHandler::spawn_blocking(move || -> Result<()> { - let file = std::fs::File::open(&target_path)?; - let mut zip = zip::ZipArchive::new(file)?; - zip.extract(&home_dir)?; - Ok(()) - }) - .await - .map_err(|join| anyhow!("backup extraction task failed: {join}"))??; - - // Held for the config-data transition only; extraction is plain filesystem work. - let _profile_write = crate::config::profiles::PROFILE_WRITE_LOCK.lock().await; - finalize_restored_verge_config(webdav_url, webdav_username, webdav_password).await?; - Ok(()) + restore_backup_archive(target_path).await } #[tracing::instrument(skip_all, level = "info", fields(filename = %filename, destination = %destination))]