From 0318a7aa9a81fa8618612cbc4497b21653773b36 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 17:00:01 +0000 Subject: [PATCH 1/2] chore: update Rust MSRV to 1.88.0 Update Rust version in flake.nix and Cargo.toml to prepare for ORT v2.0 release. - flake.nix: 1.85.0 -> 1.88.0 - frontend/src-tauri/Cargo.toml: 1.77.2 -> 1.88.0 GitHub Actions workflows already use dtolnay/rust-toolchain@stable which will automatically pick up the latest stable Rust version. Fixes #371 Co-authored-by: Anthony --- flake.lock | 18 +++++++++--------- flake.nix | 2 +- frontend/src-tauri/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/flake.lock b/flake.lock index 4ec6900f0..d338308ae 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1739736696, - "narHash": "sha256-zON2GNBkzsIyALlOCFiEBcIjI4w38GYOb+P+R4S8Jsw=", + "lastModified": 1767767207, + "narHash": "sha256-Mj3d3PfwltLmukFal5i3fFt27L6NiKXdBezC1EBuZs4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d74a2335ac9c133d6bbec9fc98d91a77f1604c1f", + "rev": "5912c1772a44e31bf1c63c0390b90501e5026886", "type": "github" }, "original": { @@ -36,11 +36,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1743568003, - "narHash": "sha256-ZID5T65E8ruHqWRcdvZLsczWDOAWIE7om+vQOREwiX0=", + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b7ba7f9f45c5cd0d8625e9e217c28f8eb6a19a76", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", "type": "github" }, "original": { @@ -62,11 +62,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1743561237, - "narHash": "sha256-dd97LXek202OWmUXvKYFdYWj0jHrn3p+L5Ojh1SEOqs=", + "lastModified": 1767926800, + "narHash": "sha256-x0n73J6ufD/EhDlVdcoAmF0OQHZ+b0a2cKDc8RZyt+o=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "1de27ae43712a971c1da100dcd84386356f03ec7", + "rev": "499e9eed88ff9494b6604205b42847e847dfeb91", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 16ed8dbfc..1db530ff4 100644 --- a/flake.nix +++ b/flake.nix @@ -16,7 +16,7 @@ }; # Use specific rust version required by Tauri - rustToolchain = pkgs.rust-bin.stable."1.85.0".default.override { + rustToolchain = pkgs.rust-bin.stable."1.88.0".default.override { extensions = [ "rust-src" ]; }; in diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml index 7cc2cbce3..4bfb6eb83 100644 --- a/frontend/src-tauri/Cargo.toml +++ b/frontend/src-tauri/Cargo.toml @@ -6,7 +6,7 @@ authors = ["tony@opensecret.cloud"] license = "MIT" repository = "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/OpenSecretCloud/Maple" edition = "2021" -rust-version = "1.77.2" +rust-version = "1.88.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 32ad6606a57e807f0c7a041b27d8e8895a4df1bd Mon Sep 17 00:00:00 2001 From: Tony Giorgio Date: Thu, 8 Jan 2026 23:05:52 -0600 Subject: [PATCH 2/2] fix: use inlined format args for Rust 1.88.0 clippy lint Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- frontend/src-tauri/src/lib.rs | 36 ++++++++--------- frontend/src-tauri/src/pdf_extractor.rs | 9 ++--- frontend/src-tauri/src/proxy.rs | 18 ++++----- frontend/src-tauri/src/tts.rs | 51 +++++++++++-------------- 4 files changed, 53 insertions(+), 61 deletions(-) diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index 1529e132d..2deadf0e7 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -15,11 +15,11 @@ fn restart_for_update(app_handle: tauri::AppHandle) { // This handles incoming deep links fn handle_deep_link_event(url: &str, app: &tauri::AppHandle) { - log::info!("[Deep Link] Received: {}", url); + log::info!("[Deep Link] Received: {url}"); // Forward the URL to the frontend match app.emit_to("main", "deep-link-received", url.to_string()) { Ok(_) => log::info!("[Deep Link] Event emitted successfully"), - Err(e) => log::error!("[Deep Link] Failed to emit event: {}", e), + Err(e) => log::error!("[Deep Link] Failed to emit event: {e}"), } } @@ -63,7 +63,7 @@ pub fn run() { // Create a new State wrapper for the async context if let Err(e) = proxy::init_proxy_on_startup_simple(app_handle_proxy).await { - log::error!("Failed to initialize proxy: {}", e); + log::error!("Failed to initialize proxy: {e}"); } }); } @@ -81,7 +81,7 @@ pub fn run() { // Optionally register the scheme at runtime #[cfg(desktop)] if let Err(e) = app.deep_link().register("cloud.opensecret.maple") { - log::error!("[Deep Link] Failed to register scheme: {}", e); + log::error!("[Deep Link] Failed to register scheme: {e}"); } // Create the application menu with update options #[cfg(desktop)] @@ -216,7 +216,7 @@ pub fn run() { { match CURRENT_VERSION.lock() { Ok(mut version) => version.clear(), - Err(e) => log::error!("Failed to lock CURRENT_VERSION mutex when clearing: {}", e) + Err(e) => log::error!("Failed to lock CURRENT_VERSION mutex when clearing: {e}") } } log::info!("Dismissal flags cleared - user will be prompted for any available updates"); @@ -228,7 +228,7 @@ pub fn run() { tauri::async_runtime::spawn(async move { match check_for_updates(app_handle_clone).await { Ok(_) => log::info!("Update check completed successfully"), - Err(e) => log::error!("Update check failed: {}", e), + Err(e) => log::error!("Update check failed: {e}"), } }); } @@ -307,8 +307,8 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { let updater = match app_handle.updater() { Ok(u) => u, Err(e) => { - log::error!("Failed to get updater: {}", e); - return Err(format!("Failed to get updater: {}", e)); + log::error!("Failed to get updater: {e}"); + return Err(format!("Failed to get updater: {e}")); } }; @@ -319,7 +319,7 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { let current_downloaded_version = match CURRENT_VERSION.lock() { Ok(guard) => guard.clone(), Err(e) => { - log::error!("Failed to lock CURRENT_VERSION mutex: {}", e); + log::error!("Failed to lock CURRENT_VERSION mutex: {e}"); String::new() // Use empty string if lock fails } }; @@ -339,9 +339,9 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { // Download the update let progress_fn = |downloaded: usize, total: Option| { if let Some(total) = total { - log::info!("Download progress: {}/{} bytes", downloaded, total); + log::info!("Download progress: {downloaded}/{total} bytes"); } else { - log::info!("Download progress: {} bytes", downloaded); + log::info!("Download progress: {downloaded} bytes"); } }; @@ -364,7 +364,7 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { { match CURRENT_VERSION.lock() { Ok(mut version) => *version = update.version.clone(), - Err(e) => log::error!("Failed to lock CURRENT_VERSION mutex when updating version: {}", e) + Err(e) => log::error!("Failed to lock CURRENT_VERSION mutex when updating version: {e}") } } @@ -391,7 +391,7 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { version: update.version.clone(), }, ) { - log::error!("Failed to emit update-ready event: {}", e); + log::error!("Failed to emit update-ready event: {e}"); } else { log::info!( "Emitted update-ready event for version {}", @@ -400,15 +400,15 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { } } Err(e) => { - log::error!("Failed to install update: {}", e); + log::error!("Failed to install update: {e}"); } } Ok(()) } Err(e) => { - log::error!("Failed to download update: {}", e); - Err(format!("Failed to download update: {}", e)) + log::error!("Failed to download update: {e}"); + Err(format!("Failed to download update: {e}")) } } } @@ -417,8 +417,8 @@ async fn check_for_updates(app_handle: tauri::AppHandle) -> Result<(), String> { Ok(()) } Err(e) => { - log::error!("Failed to check for updates: {}", e); - Err(format!("Failed to check for updates: {}", e)) + log::error!("Failed to check for updates: {e}"); + Err(format!("Failed to check for updates: {e}")) } } } diff --git a/frontend/src-tauri/src/pdf_extractor.rs b/frontend/src-tauri/src/pdf_extractor.rs index 35cc1b2d3..d4158c9c9 100644 --- a/frontend/src-tauri/src/pdf_extractor.rs +++ b/frontend/src-tauri/src/pdf_extractor.rs @@ -23,21 +23,20 @@ pub async fn extract_document_content( // Decode base64 file data let file_bytes = BASE64 .decode(&file_base64) - .map_err(|e| format!("Failed to decode base64 file: {}", e))?; + .map_err(|e| format!("Failed to decode base64 file: {e}"))?; let text_content = match file_type.as_str() { "pdf" | "application/pdf" => { // Extract text from PDF extract_text_from_mem(&file_bytes) - .map_err(|e| format!("Failed to extract text from PDF: {}", e))? + .map_err(|e| format!("Failed to extract text from PDF: {e}"))? } "txt" | "text/plain" | "md" | "text/markdown" => { // For text files, just convert bytes to string - String::from_utf8(file_bytes) - .map_err(|e| format!("Failed to decode text file: {}", e))? + String::from_utf8(file_bytes).map_err(|e| format!("Failed to decode text file: {e}"))? } _ => { - return Err(format!("Unsupported file type: {}", file_type)); + return Err(format!("Unsupported file type: {file_type}")); } }; diff --git a/frontend/src-tauri/src/proxy.rs b/frontend/src-tauri/src/proxy.rs index 3fb24cbaa..1b2053575 100644 --- a/frontend/src-tauri/src/proxy.rs +++ b/frontend/src-tauri/src/proxy.rs @@ -101,7 +101,7 @@ pub async fn start_proxy( // Try to bind to the address first to check if port is available let addr = proxy_config .socket_addr() - .map_err(|e| format!("Invalid address: {}", e))?; + .map_err(|e| format!("Invalid address: {e}"))?; let listener = match TcpListener::bind(&addr).await { Ok(listener) => listener, @@ -118,9 +118,9 @@ pub async fn start_proxy( // Spawn the proxy server let handle = tokio::spawn(async move { - log::info!("Maple proxy server running on http://{}", addr); + log::info!("Maple proxy server running on http://{addr}"); if let Err(e) = axum::serve(listener, app).await { - log::error!("Proxy server error: {}", e); + log::error!("Proxy server error: {e}"); } }); @@ -133,7 +133,7 @@ pub async fn start_proxy( // Save config to disk if let Err(e) = save_proxy_config(&config).await { - log::error!("Failed to save proxy config: {}", e); + log::error!("Failed to save proxy config: {e}"); } Ok(ProxyStatus { @@ -188,27 +188,27 @@ pub async fn get_proxy_status(state: State<'_, ProxyState>) -> Result Result { load_saved_proxy_config() .await - .map_err(|e| format!("Failed to load proxy config: {}", e)) + .map_err(|e| format!("Failed to load proxy config: {e}")) } #[tauri::command] pub async fn save_proxy_settings(config: ProxyConfig) -> Result<(), String> { save_proxy_config(&config) .await - .map_err(|e| format!("Failed to save proxy config: {}", e)) + .map_err(|e| format!("Failed to save proxy config: {e}")) } #[tauri::command] pub async fn test_proxy_port(host: String, port: u16) -> Result { // Try to bind to the address to check if it's available - let addr = format!("{}:{}", host, port); + let addr = format!("{host}:{port}"); match TcpListener::bind(&addr).await { Ok(_) => Ok(true), // Port is available Err(e) => { if e.kind() == std::io::ErrorKind::AddrInUse { Ok(false) // Port is in use } else { - Err(format!("Failed to test port: {}", e)) + Err(format!("Failed to test port: {e}")) } } } @@ -289,7 +289,7 @@ pub async fn init_proxy_on_startup_simple(app_handle: AppHandle) -> Result<()> { let _ = app_handle.emit("proxy-autostarted", &config); } Err(e) => { - log::error!("Failed to auto-start proxy: {}", e); + log::error!("Failed to auto-start proxy: {e}"); // Emit an event to notify the frontend of the failure let _ = app_handle.emit("proxy-autostart-failed", e); } diff --git a/frontend/src-tauri/src/tts.rs b/frontend/src-tauri/src/tts.rs index b132bb13f..5c5f25666 100644 --- a/frontend/src-tauri/src/tts.rs +++ b/frontend/src-tauri/src/tts.rs @@ -757,13 +757,13 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { let models_dir = get_tts_models_dir().map_err(|e| e.to_string())?; fs::create_dir_all(&models_dir) - .map_err(|e| format!("Failed to create models directory: {}", e))?; + .map_err(|e| format!("Failed to create models directory: {e}"))?; let client = reqwest::Client::builder() .timeout(Duration::from_secs(300)) .connect_timeout(Duration::from_secs(30)) .build() - .map_err(|e| format!("Failed to create HTTP client: {}", e))?; + .map_err(|e| format!("Failed to create HTTP client: {e}"))?; let mut total_downloaded: u64 = 0; for (file_name, url_path, expected_size, expected_sha256) in MODEL_FILES { @@ -795,17 +795,14 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { // Clean up any partial download from previous attempt let _ = fs::remove_file(&temp_path); - let url = format!( - "{}/{}/{}", - HUGGINGFACE_BASE_URL, HUGGINGFACE_REVISION, url_path - ); - log::info!("Downloading TTS model: {}", file_name); + let url = format!("{HUGGINGFACE_BASE_URL}/{HUGGINGFACE_REVISION}/{url_path}"); + log::info!("Downloading TTS model: {file_name}"); let response = client .get(&url) .send() .await - .map_err(|e| format!("Failed to download {}: {}", file_name, e))?; + .map_err(|e| format!("Failed to download {file_name}: {e}"))?; if !response.status().is_success() { return Err(format!( @@ -819,15 +816,15 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { let mut hasher = Sha256::new(); let mut file = File::create(&temp_path) - .map_err(|e| format!("Failed to create file {}: {}", file_name, e))?; + .map_err(|e| format!("Failed to create file {file_name}: {e}"))?; let mut stream = response.bytes_stream(); let mut file_downloaded: u64 = 0; while let Some(chunk) = stream.next().await { - let chunk = chunk.map_err(|e| format!("Download error: {}", e))?; + let chunk = chunk.map_err(|e| format!("Download error: {e}"))?; file.write_all(&chunk) - .map_err(|e| format!("Write error: {}", e))?; + .map_err(|e| format!("Write error: {e}"))?; hasher.update(&chunk); @@ -850,8 +847,7 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { drop(file); let _ = fs::remove_file(&temp_path); return Err(format!( - "Incomplete download for {}: expected {} bytes, got {}", - file_name, expected_len, file_downloaded + "Incomplete download for {file_name}: expected {expected_len} bytes, got {file_downloaded}" )); } } @@ -860,8 +856,7 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { drop(file); let _ = fs::remove_file(&temp_path); return Err(format!( - "Unexpected download size for {}: expected {} bytes, got {}", - file_name, expected_size, file_downloaded + "Unexpected download size for {file_name}: expected {expected_size} bytes, got {file_downloaded}" )); } @@ -870,22 +865,21 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { drop(file); let _ = fs::remove_file(&temp_path); return Err(format!( - "Checksum mismatch for {}: expected {}, got {}", - file_name, expected_sha256, actual_sha256 + "Checksum mismatch for {file_name}: expected {expected_sha256}, got {actual_sha256}" )); } // Flush and rename temp file to final path file.flush() - .map_err(|e| format!("Failed to flush file {}: {}", file_name, e))?; + .map_err(|e| format!("Failed to flush file {file_name}: {e}"))?; file.sync_all() - .map_err(|e| format!("Failed to sync file {}: {}", file_name, e))?; + .map_err(|e| format!("Failed to sync file {file_name}: {e}"))?; drop(file); fs::rename(&temp_path, &file_path) - .map_err(|e| format!("Failed to finalize {}: {}", file_name, e))?; + .map_err(|e| format!("Failed to finalize {file_name}: {e}"))?; total_downloaded += expected_size; - log::info!("Downloaded TTS model: {}", file_name); + log::info!("Downloaded TTS model: {file_name}"); } Ok(()) @@ -895,12 +889,12 @@ pub async fn tts_download_models(app: AppHandle) -> Result<(), String> { pub async fn tts_load_models(state: tauri::State<'_, Mutex>) -> Result<(), String> { let models_dir = get_tts_models_dir().map_err(|e| e.to_string())?; - log::info!("Loading TTS models from {:?}", models_dir); + log::info!("Loading TTS models from {models_dir:?}"); let tts = - load_tts_engine(&models_dir).map_err(|e| format!("Failed to load TTS engine: {}", e))?; + load_tts_engine(&models_dir).map_err(|e| format!("Failed to load TTS engine: {e}"))?; let style = - load_voice_style(&models_dir).map_err(|e| format!("Failed to load voice style: {}", e))?; + load_voice_style(&models_dir).map_err(|e| format!("Failed to load voice style: {e}"))?; { let mut guard = state.lock().map_err(|e| e.to_string())?; @@ -940,7 +934,7 @@ pub async fn tts_synthesize( let audio = tts .synthesize(&text, &style, 10, 1.2) - .map_err(|e| format!("TTS synthesis failed: {}", e))?; + .map_err(|e| format!("TTS synthesis failed: {e}"))?; if audio.is_empty() { return Err("No speakable text after preprocessing".to_string()); @@ -953,9 +947,9 @@ pub async fn tts_synthesize( drop(guard); let audio_base64 = - wav_to_base64(&audio, sample_rate).map_err(|e| format!("Failed to encode audio: {}", e))?; + wav_to_base64(&audio, sample_rate).map_err(|e| format!("Failed to encode audio: {e}"))?; - log::info!("TTS synthesis complete: {:.2}s audio", duration_seconds); + log::info!("TTS synthesis complete: {duration_seconds:.2}s audio"); Ok(TTSSynthesizeResponse { audio_base64, @@ -985,8 +979,7 @@ pub async fn tts_delete_models(state: tauri::State<'_, Mutex>) -> Resu // Delete the models directory let models_dir = get_tts_models_dir().map_err(|e| e.to_string())?; if models_dir.exists() { - fs::remove_dir_all(&models_dir) - .map_err(|e| format!("Failed to delete TTS models: {}", e))?; + fs::remove_dir_all(&models_dir).map_err(|e| format!("Failed to delete TTS models: {e}"))?; } log::info!("TTS models deleted");