From f013026e745adc2054f3bab442542d755bf756df Mon Sep 17 00:00:00 2001 From: careck Date: Tue, 28 Apr 2026 16:30:43 +1000 Subject: [PATCH 1/4] fix: resolve cargo fmt and clippy errors breaking CI All CI runs were failing at `cargo fmt --check` (3 formatting diffs), with 35 additional clippy warnings-as-errors hidden behind the gate. --- krillnotes-core/src/core/export_tests.rs | 16 +++----- krillnotes-core/src/core/identity.rs | 2 +- .../src/core/scripting/display_helpers.rs | 7 +--- krillnotes-core/src/core/scripting/engine.rs | 2 +- krillnotes-core/src/core/scripting/mod.rs | 4 +- krillnotes-core/src/core/scripting/schema.rs | 2 + krillnotes-core/src/core/sync/channel.rs | 9 +---- krillnotes-core/src/core/sync/folder.rs | 2 +- .../src/core/workspace/attachments.rs | 2 +- krillnotes-core/src/core/workspace/hooks.rs | 4 +- krillnotes-core/src/core/workspace/notes.rs | 6 +-- krillnotes-core/src/core/workspace/sync.rs | 12 ++++-- krillnotes-core/src/core/workspace/undo.rs | 10 ++--- .../src/commands/accepted_invites.rs | 1 + .../src-tauri/src/commands/identity.rs | 39 +++++++++---------- .../src-tauri/src/commands/invites.rs | 1 + .../src-tauri/src/commands/notes.rs | 4 +- .../src-tauri/src/commands/sync.rs | 1 + .../src-tauri/src/commands/workspace.rs | 7 ++-- krillnotes-desktop/src-tauri/src/lib.rs | 1 + krillnotes-desktop/src-tauri/src/menu.rs | 1 + krillnotes-rbac/src/resolver.rs | 1 + 22 files changed, 68 insertions(+), 66 deletions(-) diff --git a/krillnotes-core/src/core/export_tests.rs b/krillnotes-core/src/core/export_tests.rs index e792bdcf..04cc34e7 100644 --- a/krillnotes-core/src/core/export_tests.rs +++ b/krillnotes-core/src/core/export_tests.rs @@ -636,15 +636,8 @@ fn test_import_stamps_importer_identity_on_notes() { ) .unwrap(); - let ws_b = Workspace::open( - temp_dst.path(), - "", - "identity-b", - key_b, - test_gate(), - None, - ) - .unwrap(); + let ws_b = + Workspace::open(temp_dst.path(), "", "identity-b", key_b, test_gate(), None).unwrap(); // Importer is owner assert!(ws_b.is_owner(), "importer should be workspace owner"); @@ -1150,5 +1143,8 @@ fn test_import_makes_importer_the_owner() { pubkey_b, "importer should become workspace owner after import" ); - assert!(imported_ws.is_owner(), "importer should be recognized as owner"); + assert!( + imported_ws.is_owner(), + "importer should be recognized as owner" + ); } diff --git a/krillnotes-core/src/core/identity.rs b/krillnotes-core/src/core/identity.rs index ca728fa2..d46f2920 100644 --- a/krillnotes-core/src/core/identity.rs +++ b/krillnotes-core/src/core/identity.rs @@ -460,7 +460,7 @@ impl IdentityManager { /// Reads each identity file until a match is found. Returns `None` if /// no local identity has that public key. pub fn lookup_display_name(&self, public_key: &str) -> Option { - for (_uuid, folder_name) in &self.folder_cache { + for folder_name in self.folder_cache.values() { let identity_json = self .home_dir .join(folder_name) diff --git a/krillnotes-core/src/core/scripting/display_helpers.rs b/krillnotes-core/src/core/scripting/display_helpers.rs index c5921985..e9db86a2 100644 --- a/krillnotes-core/src/core/scripting/display_helpers.rs +++ b/krillnotes-core/src/core/scripting/display_helpers.rs @@ -221,10 +221,7 @@ pub fn table(headers: Array, rows: Array) -> String { out.push_str(""); if let Ok(cells) = row.clone().try_cast::().ok_or(()) { for cell in &cells { - out.push_str(&format!( - "{}", - cell.to_string() - )); + out.push_str(&format!("{cell}",)); } } out.push_str(""); @@ -316,7 +313,7 @@ pub fn view_text(content: String) -> String { pub fn list(items: Array) -> String { let mut out = String::from("
    "); for item in &items { - out.push_str(&format!("
  • {}
  • ", item.to_string())); + out.push_str(&format!("
  • {item}
  • ")); } out.push_str("
"); out diff --git a/krillnotes-core/src/core/scripting/engine.rs b/krillnotes-core/src/core/scripting/engine.rs index e01d9ff3..7d09939f 100644 --- a/krillnotes-core/src/core/scripting/engine.rs +++ b/krillnotes-core/src/core/scripting/engine.rs @@ -556,7 +556,7 @@ impl ScriptRegistry { // argument means Rhai will dispatch any value type to this function. engine.register_raw_fn( "set_field", - &[ + [ std::any::TypeId::of::(), std::any::TypeId::of::(), std::any::TypeId::of::(), diff --git a/krillnotes-core/src/core/scripting/mod.rs b/krillnotes-core/src/core/scripting/mod.rs index 9c374da8..fab71b24 100644 --- a/krillnotes-core/src/core/scripting/mod.rs +++ b/krillnotes-core/src/core/scripting/mod.rs @@ -33,7 +33,7 @@ use std::sync::{Arc, Mutex}; // ── Thread-local SaveTransaction for Rhai write-path hooks ──────────────────── thread_local! { - static SAVE_TX: RefCell> = RefCell::new(None); + static SAVE_TX: RefCell> = const { RefCell::new(None) }; } /// Sets the active [`SaveTransaction`] for the current thread. @@ -308,6 +308,7 @@ impl ScriptRegistry { /// /// Returns [`KrillnotesError::Scripting`] if the hook throws a Rhai error /// or returns a malformed map. + #[allow(clippy::too_many_arguments)] pub fn run_on_add_child_hook( &self, parent_schema_name: &str, @@ -368,6 +369,7 @@ impl ScriptRegistry { } /// Returns `(schema_name, schema_version, migrations, ast)` for every registered schema. + #[allow(clippy::type_complexity)] pub fn get_versioned_schemas( &self, ) -> Vec<( diff --git a/krillnotes-core/src/core/scripting/schema.rs b/krillnotes-core/src/core/scripting/schema.rs index 585f2640..89b450cd 100644 --- a/krillnotes-core/src/core/scripting/schema.rs +++ b/krillnotes-core/src/core/scripting/schema.rs @@ -626,6 +626,7 @@ impl SchemaRegistry { /// Returns `(schema_name, schema_version, migrations, ast)` for every registered schema. /// Used by the Phase D migration pipeline to detect and migrate stale notes. + #[allow(clippy::type_complexity)] pub(super) fn get_versioned_schemas( &self, ) -> Vec<( @@ -1022,6 +1023,7 @@ impl SchemaRegistry { /// /// The hook must use the gated SaveTransaction API (`set_field`, `set_title`, `commit`). /// Hooks that return a map (old-style direct mutation) are rejected with a migration error. + #[allow(clippy::too_many_arguments)] pub(super) fn run_on_add_child_hook( &self, engine: &Engine, diff --git a/krillnotes-core/src/core/sync/channel.rs b/krillnotes-core/src/core/sync/channel.rs index b9dcccb5..b8235969 100644 --- a/krillnotes-core/src/core/sync/channel.rs +++ b/krillnotes-core/src/core/sync/channel.rs @@ -17,20 +17,15 @@ pub enum SendResult { NotDelivered { reason: String }, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum ChannelType { Relay, Folder, + #[default] Manual, } -impl Default for ChannelType { - fn default() -> Self { - ChannelType::Manual - } -} - impl std::fmt::Display for ChannelType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/krillnotes-core/src/core/sync/folder.rs b/krillnotes-core/src/core/sync/folder.rs index 2d27f0d3..8af0307a 100644 --- a/krillnotes-core/src/core/sync/folder.rs +++ b/krillnotes-core/src/core/sync/folder.rs @@ -79,7 +79,7 @@ impl FolderChannel { for entry in entries.flatten() { let path = entry.path(); - if path.extension().map_or(true, |ext| ext != "swarm") { + if path.extension().is_none_or(|ext| ext != "swarm") { continue; } diff --git a/krillnotes-core/src/core/workspace/attachments.rs b/krillnotes-core/src/core/workspace/attachments.rs index 6c55c1d7..c31d559a 100644 --- a/krillnotes-core/src/core/workspace/attachments.rs +++ b/krillnotes-core/src/core/workspace/attachments.rs @@ -431,7 +431,7 @@ impl Workspace { meta.note_id, meta.filename, meta.mime_type, - meta.size_bytes as i64, + meta.size_bytes, meta.hash_sha256, salt_bytes.as_slice(), meta.created_at, diff --git a/krillnotes-core/src/core/workspace/hooks.rs b/krillnotes-core/src/core/workspace/hooks.rs index c3b9d8d1..87c116f9 100644 --- a/krillnotes-core/src/core/workspace/hooks.rs +++ b/krillnotes-core/src/core/workspace/hooks.rs @@ -358,7 +358,7 @@ impl Workspace { iters += 1; if iters > new_creates.len() * new_creates.len() + 1 { // Cycle guard — should never happen in practice; break to avoid infinite loop. - ordered_creates.extend(new_creates.drain(..)); + ordered_creates.append(&mut new_creates); break; } let mut next = Vec::with_capacity(new_creates.len()); @@ -386,7 +386,7 @@ impl Workspace { new_creates = next; if new_creates.len() == remaining { // No progress — break to avoid infinite loop. - ordered_creates.extend(new_creates.drain(..)); + ordered_creates.append(&mut new_creates); break; } remaining = new_creates.len(); diff --git a/krillnotes-core/src/core/workspace/notes.rs b/krillnotes-core/src/core/workspace/notes.rs index 0c181ec9..aa8f0d44 100644 --- a/krillnotes-core/src/core/workspace/notes.rs +++ b/krillnotes-core/src/core/workspace/notes.rs @@ -435,7 +435,7 @@ impl Workspace { device_id: self.device_id.clone(), note_id: new_id.clone(), parent_id: new_parent, - position: this_position as f64, + position: this_position, schema: note.schema.clone(), title: note.title.clone(), fields: note.fields.clone(), @@ -913,8 +913,6 @@ impl Workspace { /// HTML view when no hook is registered. /// /// The default view auto-renders `textarea` fields as CommonMark markdown. - /// - pub fn toggle_note_expansion(&mut self, note_id: &str) -> Result<()> { let tx = self.storage.connection_mut().transaction()?; @@ -1695,7 +1693,7 @@ impl Workspace { /// 1. Evaluate group visibility /// 2. Run field `validate` closures (only on visible fields) /// 3. Check required constraints (only on visible fields) - /// 4-7. Delegate to `update_note` (on_save hook + DB write) + /// 4-7. Delegate to `update_note` (on_save hook + DB write) /// /// Returns `SaveResult::ValidationErrors` when any step produces errors. /// Returns `SaveResult::Ok(note)` on success. diff --git a/krillnotes-core/src/core/workspace/sync.rs b/krillnotes-core/src/core/workspace/sync.rs index 24a87fb4..adad391f 100644 --- a/krillnotes-core/src/core/workspace/sync.rs +++ b/krillnotes-core/src/core/workspace/sync.rs @@ -422,8 +422,14 @@ impl Workspace { // 6. Apply the state change to working tables. let mut scripts_changed = false; // (attachment_id, note_id, filename, mime_type, blob) - let mut pending_attachment: Option<(String, String, String, Option, Vec)> = - None; + #[allow(clippy::type_complexity)] + let mut pending_attachment: Option<( + String, + String, + String, + Option, + Vec, + )> = None; let mut pending_attachment_delete: Option = None; let tx = self.storage.connection_mut().transaction()?; match &op { @@ -738,7 +744,7 @@ impl Workspace { pub fn import_snapshot_json(&mut self, data: &[u8]) -> Result { log::info!(target: "krillnotes::sync", "importing snapshot ({} bytes)", data.len()); let snapshot: WorkspaceSnapshot = - serde_json::from_slice(data).map_err(|e| KrillnotesError::Json(e))?; + serde_json::from_slice(data).map_err(KrillnotesError::Json)?; let note_count = snapshot.notes.len(); log::debug!(target: "krillnotes::sync", "snapshot contains {} notes, {} scripts", note_count, snapshot.user_scripts.len()); diff --git a/krillnotes-core/src/core/workspace/undo.rs b/krillnotes-core/src/core/workspace/undo.rs index acbf705b..8632005e 100644 --- a/krillnotes-core/src/core/workspace/undo.rs +++ b/krillnotes-core/src/core/workspace/undo.rs @@ -116,7 +116,7 @@ impl Workspace { /// The value is clamped to `[1, 500]`. If the new limit is smaller than /// the current stack depth, the oldest entries are dropped. pub fn set_undo_limit(&mut self, limit: usize) -> Result<()> { - let limit = limit.max(1).min(500); + let limit = limit.clamp(1, 500); self.storage.connection().execute( "INSERT OR REPLACE INTO workspace_meta (key, value) VALUES ('undo_limit', ?)", [limit.to_string()], @@ -331,13 +331,13 @@ impl Workspace { /// would require: /// /// - `DeleteNote` (undo was: un-do a CreateNote) → redo re-deletes. - /// Build `SubtreeRestore` from current state. + /// Build `SubtreeRestore` from current state. /// - `SubtreeRestore` (undo was: un-do a DeleteNote) → redo re-deletes root. - /// Build `DeleteNote`. + /// Build `DeleteNote`. /// - `NoteRestore` → redo re-updates. Capture current state as `NoteRestore`. /// - `PositionRestore`→ redo re-moves. Capture current position as `PositionRestore`. /// - `DeleteScript` → redo re-deletes. Script no longer exists post-undo; - /// use a stub `ScriptRestore` (deletion needs no data). + /// use a stub `ScriptRestore` (deletion needs no data). /// - `ScriptRestore` → redo re-restores. Build `DeleteScript`. /// - `Batch` → recurse in reverse LIFO order. fn build_redo_inverse(&self, undo_entry: &UndoEntry) -> Result { @@ -520,7 +520,7 @@ impl Workspace { VALUES (?,?,?,?,?,?,?,?)", rusqlite::params![ att.id, att.note_id, att.filename, att.mime_type, - att.size_bytes as i64, att.hash_sha256, + att.size_bytes, att.hash_sha256, salt_bytes.as_slice(), att.created_at, ], )?; diff --git a/krillnotes-desktop/src-tauri/src/commands/accepted_invites.rs b/krillnotes-desktop/src-tauri/src/commands/accepted_invites.rs index 6d68b404..0dbc3d32 100644 --- a/krillnotes-desktop/src-tauri/src/commands/accepted_invites.rs +++ b/krillnotes-desktop/src-tauri/src/commands/accepted_invites.rs @@ -70,6 +70,7 @@ pub fn list_accepted_invites( Ok(records.into_iter().map(AcceptedInviteInfo::from).collect()) } +#[allow(clippy::too_many_arguments)] #[tauri::command] pub fn save_accepted_invite( state: State<'_, AppState>, diff --git a/krillnotes-desktop/src-tauri/src/commands/identity.rs b/krillnotes-desktop/src-tauri/src/commands/identity.rs index f59f5f88..1748fe71 100644 --- a/krillnotes-desktop/src-tauri/src/commands/identity.rs +++ b/krillnotes-desktop/src-tauri/src/commands/identity.rs @@ -348,28 +348,25 @@ pub fn unlock_identity( &account.relay_url, ); id_client.set_session_token(&session.session_token); - match id_client.add_device(&identity_pubkey_hex) { - Ok(result) => { - if let Ok(nonce) = - krillnotes_core::core::sync::relay::auth::decrypt_pop_challenge( - &identity_signing_key, - &result.challenge.encrypted_nonce, - &result.challenge.server_public_key, - ) - { - let _ = id_client.verify_device( - &identity_pubkey_hex, - &hex::encode(&nonce), - None, - ); - log::info!( - "Registered identity public key on {}", - account.relay_url - ); - } + if let Ok(result) = id_client.add_device(&identity_pubkey_hex) { + if let Ok(nonce) = + krillnotes_core::core::sync::relay::auth::decrypt_pop_challenge( + &identity_signing_key, + &result.challenge.encrypted_nonce, + &result.challenge.server_public_key, + ) + { + let _ = id_client.verify_device( + &identity_pubkey_hex, + &hex::encode(&nonce), + None, + ); + log::info!( + "Registered identity public key on {}", + account.relay_url + ); } - Err(_) => {} // 409 KEY_EXISTS expected - } + } // Err: 409 KEY_EXISTS expected } // Update account with new session + device key diff --git a/krillnotes-desktop/src-tauri/src/commands/invites.rs b/krillnotes-desktop/src-tauri/src/commands/invites.rs index 6783a27e..04481879 100644 --- a/krillnotes-desktop/src-tauri/src/commands/invites.rs +++ b/krillnotes-desktop/src-tauri/src/commands/invites.rs @@ -97,6 +97,7 @@ pub fn list_invites( Ok(records.into_iter().map(InviteInfo::from).collect()) } +#[allow(clippy::too_many_arguments)] #[tauri::command] pub fn create_invite( window: tauri::Window, diff --git a/krillnotes-desktop/src-tauri/src/commands/notes.rs b/krillnotes-desktop/src-tauri/src/commands/notes.rs index cb7edbe6..d8bb3dd5 100644 --- a/krillnotes-desktop/src-tauri/src/commands/notes.rs +++ b/krillnotes-desktop/src-tauri/src/commands/notes.rs @@ -517,7 +517,9 @@ pub fn get_note_verified_by( let label = window.label(); let workspaces = state.workspaces.lock().expect("Mutex poisoned"); let ws = workspaces.get(label).ok_or("No workspace open")?; - let raw_key = ws.get_note_verified_by(¬e_id).map_err(|e| e.to_string())?; + let raw_key = ws + .get_note_verified_by(¬e_id) + .map_err(|e| e.to_string())?; if raw_key.is_empty() { return Ok(String::new()); diff --git a/krillnotes-desktop/src-tauri/src/commands/sync.rs b/krillnotes-desktop/src-tauri/src/commands/sync.rs index 1d2c7c85..1e966b7a 100644 --- a/krillnotes-desktop/src-tauri/src/commands/sync.rs +++ b/krillnotes-desktop/src-tauri/src/commands/sync.rs @@ -251,6 +251,7 @@ pub async fn poll_sync( /// One-click command: create an invite + upload it to the relay + return the /// shareable URL. The invite record is persisted with `relay_url` set. +#[allow(clippy::too_many_arguments)] #[tauri::command] pub async fn share_invite_link( window: Window, diff --git a/krillnotes-desktop/src-tauri/src/commands/workspace.rs b/krillnotes-desktop/src-tauri/src/commands/workspace.rs index f9cf1bee..2ebf51d3 100644 --- a/krillnotes-desktop/src-tauri/src/commands/workspace.rs +++ b/krillnotes-desktop/src-tauri/src/commands/workspace.rs @@ -488,7 +488,7 @@ pub async fn create_workspace( use rand::RngCore; let mut bytes = [0u8; 32]; rand::rng().fill_bytes(&mut bytes); - base64::engine::general_purpose::STANDARD.encode(&bytes) + base64::engine::general_purpose::STANDARD.encode(bytes) }; // Get the signing key from the unlocked identity before creating the workspace. @@ -804,7 +804,7 @@ pub async fn execute_import( use rand::RngCore; let mut bytes = [0u8; 32]; rand::rng().fill_bytes(&mut bytes); - base64::engine::general_purpose::STANDARD.encode(&bytes) + base64::engine::general_purpose::STANDARD.encode(bytes) }; let import_seed = { let identities = state.unlocked_identities.lock().expect("Mutex poisoned"); @@ -1066,6 +1066,7 @@ fn dir_size_bytes(dir: &Path) -> u64 { /// Reads `info.json` from `workspace_dir` and returns all stored fields. /// Returns `(None, None, None, None, None)` if the file is missing or malformed. +#[allow(clippy::type_complexity)] pub fn read_info_json_full( workspace_dir: &Path, ) -> ( @@ -1297,7 +1298,7 @@ pub fn duplicate_workspace( use rand::RngCore; let mut bytes = [0u8; 32]; rand::rng().fill_bytes(&mut bytes); - base64::engine::general_purpose::STANDARD.encode(&bytes) + base64::engine::general_purpose::STANDARD.encode(bytes) }; // Derive the signing key for the copy operation (identity_uuid is the function parameter). diff --git a/krillnotes-desktop/src-tauri/src/lib.rs b/krillnotes-desktop/src-tauri/src/lib.rs index 30599fe8..0f738a36 100644 --- a/krillnotes-desktop/src-tauri/src/lib.rs +++ b/krillnotes-desktop/src-tauri/src/lib.rs @@ -36,6 +36,7 @@ use tauri::{AppHandle, Manager}; /// Each window label maps to its open [`Workspace`] and the filesystem path /// of its database file. Both maps are protected by a [`Mutex`] since Tauri /// may call commands from multiple threads. +#[allow(clippy::type_complexity)] pub struct AppState { /// Map from window label to the open [`Workspace`] for that window. pub workspaces: Arc>>, diff --git a/krillnotes-desktop/src-tauri/src/menu.rs b/krillnotes-desktop/src-tauri/src/menu.rs index 3aa48b19..83986ea4 100644 --- a/krillnotes-desktop/src-tauri/src/menu.rs +++ b/krillnotes-desktop/src-tauri/src/menu.rs @@ -43,6 +43,7 @@ struct WorkspaceMenuResult { /// /// On macOS: App menu (Krillnotes), File, Edit, Workspace, View. /// On other platforms: File, Edit, Workspace, View, Help. +#[allow(clippy::needless_return)] pub fn build_menu( app: &AppHandle, strings: &Value, diff --git a/krillnotes-rbac/src/resolver.rs b/krillnotes-rbac/src/resolver.rs index cc4a7118..ce567084 100644 --- a/krillnotes-rbac/src/resolver.rs +++ b/krillnotes-rbac/src/resolver.rs @@ -16,6 +16,7 @@ pub enum Role { } impl Role { + #[allow(clippy::should_implement_trait)] pub fn from_str(s: &str) -> Option { match s { "owner" => Some(Self::Owner), From 467f44ac31cf1c25790e87559c6fe88078456a75 Mon Sep 17 00:00:00 2001 From: careck Date: Tue, 28 Apr 2026 16:46:19 +1000 Subject: [PATCH 2/4] fix: resolve Rust 1.95 clippy lints (sort_by_key, collapsible_match) CI runs Rust 1.95 stable which has stricter lints than local 1.93. --- krillnotes-core/src/core/accepted_invite.rs | 2 +- krillnotes-core/src/core/identity.rs | 2 +- krillnotes-core/src/core/invite.rs | 2 +- krillnotes-core/src/core/received_response.rs | 2 +- krillnotes-core/src/core/workspace/notes.rs | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/krillnotes-core/src/core/accepted_invite.rs b/krillnotes-core/src/core/accepted_invite.rs index befcae5c..c9c41fac 100644 --- a/krillnotes-core/src/core/accepted_invite.rs +++ b/krillnotes-core/src/core/accepted_invite.rs @@ -112,7 +112,7 @@ impl AcceptedInviteManager { } } } - records.sort_by(|a, b| b.accepted_at.cmp(&a.accepted_at)); + records.sort_by_key(|r| std::cmp::Reverse(r.accepted_at)); Ok(records) } diff --git a/krillnotes-core/src/core/identity.rs b/krillnotes-core/src/core/identity.rs index d46f2920..e6976c5c 100644 --- a/krillnotes-core/src/core/identity.rs +++ b/krillnotes-core/src/core/identity.rs @@ -452,7 +452,7 @@ impl IdentityManager { } } } - refs.sort_by(|a, b| b.last_used.cmp(&a.last_used)); + refs.sort_by_key(|r| std::cmp::Reverse(r.last_used)); Ok(refs) } diff --git a/krillnotes-core/src/core/invite.rs b/krillnotes-core/src/core/invite.rs index 26dab3ad..e7bfae60 100644 --- a/krillnotes-core/src/core/invite.rs +++ b/krillnotes-core/src/core/invite.rs @@ -296,7 +296,7 @@ impl InviteManager { let record: InviteRecord = serde_json::from_str(&json)?; records.push(record); } - records.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + records.sort_by_key(|r| std::cmp::Reverse(r.created_at)); Ok(records) } diff --git a/krillnotes-core/src/core/received_response.rs b/krillnotes-core/src/core/received_response.rs index f9084a57..1f25be51 100644 --- a/krillnotes-core/src/core/received_response.rs +++ b/krillnotes-core/src/core/received_response.rs @@ -119,7 +119,7 @@ impl ReceivedResponseManager { } } } - records.sort_by(|a, b| b.received_at.cmp(&a.received_at)); + records.sort_by_key(|r| std::cmp::Reverse(r.received_at)); Ok(records) } diff --git a/krillnotes-core/src/core/workspace/notes.rs b/krillnotes-core/src/core/workspace/notes.rs index aa8f0d44..c7df8dab 100644 --- a/krillnotes-core/src/core/workspace/notes.rs +++ b/krillnotes-core/src/core/workspace/notes.rs @@ -814,10 +814,10 @@ impl Workspace { } for value in n.fields.values() { match value { - FieldValue::Text(s) | FieldValue::Email(s) => { - if s.to_lowercase().contains(&query_lower) { - return true; - } + FieldValue::Text(s) | FieldValue::Email(s) + if s.to_lowercase().contains(&query_lower) => + { + return true; } _ => {} } From d430a9897e4c60894befa808dccf3403d8b9a127 Mon Sep 17 00:00:00 2001 From: careck Date: Tue, 28 Apr 2026 16:52:09 +1000 Subject: [PATCH 3/4] fix: resolve collapsible_match lint in rbac gate (Rust 1.95) --- krillnotes-rbac/src/gate.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/krillnotes-rbac/src/gate.rs b/krillnotes-rbac/src/gate.rs index a14786c7..8e2d3567 100644 --- a/krillnotes-rbac/src/gate.rs +++ b/krillnotes-rbac/src/gate.rs @@ -72,10 +72,8 @@ impl RbacGate { | Operation::SetTags { .. } => { require_at_least(role, Role::Writer)?; } - Operation::DeleteNote { note_id, .. } => { - if role < Role::Owner { - self.require_authorship(conn, actor, note_id, role)?; - } + Operation::DeleteNote { note_id, .. } if role < Role::Owner => { + self.require_authorship(conn, actor, note_id, role)?; } Operation::MoveNote { note_id, From fce8a72a6b5005ccf36a931f958114314e3c36ea Mon Sep 17 00:00:00 2001 From: careck Date: Tue, 28 Apr 2026 17:10:16 +1000 Subject: [PATCH 4/4] fix: resolve Linux-only clippy lints (unused var behind cfg, sort_by_key) --- krillnotes-desktop/src-tauri/src/commands/workspace.rs | 2 +- krillnotes-desktop/src-tauri/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/krillnotes-desktop/src-tauri/src/commands/workspace.rs b/krillnotes-desktop/src-tauri/src/commands/workspace.rs index 2ebf51d3..88a8ea71 100644 --- a/krillnotes-desktop/src-tauri/src/commands/workspace.rs +++ b/krillnotes-desktop/src-tauri/src/commands/workspace.rs @@ -1196,7 +1196,7 @@ pub fn list_workspace_files( // Drop the identity manager lock before sorting drop(mgr); - entries.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase())); + entries.sort_by_key(|a| a.name.to_lowercase()); Ok(entries) } diff --git a/krillnotes-desktop/src-tauri/src/lib.rs b/krillnotes-desktop/src-tauri/src/lib.rs index 0f738a36..a08e7c4d 100644 --- a/krillnotes-desktop/src-tauri/src/lib.rs +++ b/krillnotes-desktop/src-tauri/src/lib.rs @@ -553,19 +553,19 @@ pub fn run() { ]) .build(tauri::generate_context!()) .expect("error while building tauri application") - .run(|app_handle, event| { + .run(|_app_handle, event| { // macOS warm-start and cold-start: the OS delivers file-open events via the // NSApplicationDelegate applicationOpenURLs: callback, which Tauri surfaces // here as RunEvent::Opened. On Windows and Linux the OS spawns a fresh // process instead, so files arrive via std::env::args() in setup(). #[cfg(target_os = "macos")] if let tauri::RunEvent::Opened { urls } = &event { - let state = app_handle.state::(); + let state = _app_handle.state::(); for url in urls { if url.scheme() == "file" { let path = PathBuf::from(url.path()); if path.exists() { - commands::workspace::handle_file_opened(app_handle, &state, path); + commands::workspace::handle_file_opened(_app_handle, &state, path); } } }