chore(rust): clear the clippy backlog and finish the poison-tolerant lock sweep
`cargo clippy --all-targets` went from 51 warnings (23 in the lib) to zero. Most were mechanical — needless borrows, `assert_eq!` against a bool literal, `vec!` where an array does, `or_insert_with(Vec::new)`, a loop index used only to index — and were applied with `clippy --fix`, then reviewed line by line. That review caught one auto-fix that was *not* semantically neutral: dropping the redundant `use hostname;` left its `#[cfg(target_os = "linux")]` orphaned directly above `SERVICE_NAME`, which would have silently cfg'd the constant out of every non-Linux build. Removed the stray attribute with the import. Where a lint asked for a risky change rather than a better one, it is suppressed with a comment saying why: - `too_many_arguments` on five `#[tauri::command]` handlers and `ThumbnailCache::save_thumbnail` — most of the arity is `State<'_, _>` injection, and a parameter struct would change the IPC contract and the generated TypeScript for no readability gain. - `large_enum_variant` on `PlayerStatusEvent` and `AutoplayDecision` — both are serde + specta wire types emitted a handful of times a second, never bulk allocated; boxing would have to stay invisible to the generated bindings while every match arm gained a deref. - `await_holding_lock` on the `hybrid`/`offline` test modules — the guard is a test-only serialisation lock for the process-global `INCLUDE_CATALOG_BROWSE` flag, and the await it spans *is* the critical section. Each `#[tokio::test]` gets its own single-threaded runtime, so this is not the production deadlock class the lint targets; restructuring would reintroduce the flag race. Real fixes elsewhere: `JellyfinItem::to_media_item` takes `self` by value, so it is now `into_media_item`; the five-tuple episode row in the download commands has a named `EpisodeRow` alias; the mpv `PropertyChange` arm matches `name: "pause"` instead of guarding on it. Also converted the last 27 raw `.lock().unwrap()` call sites to `lock_safe()`, completing the `MutexSafe`/`RwLockSafe` convention. All of them turned out to be in test modules — production code was already clean — so this is consistency rather than a fix. The two raw locks in `utils/lock.rs` stay raw on purpose: those tests deliberately poison a mutex to prove the helpers recover from it. Pure refactoring: all 698 tests still pass.
This commit is contained in:
@@ -19,6 +19,10 @@ mod smart_cache;
|
||||
pub use pinning::*;
|
||||
pub use smart_cache::*;
|
||||
|
||||
/// One row of the series episode listing used when queueing a whole series:
|
||||
/// `(id, name, season_name, index_number, parent_index_number)`.
|
||||
type EpisodeRow = (String, String, Option<String>, Option<i32>, Option<i32>);
|
||||
|
||||
/// Wrapper for DownloadManager to be used as Tauri state
|
||||
pub struct DownloadManagerWrapper(pub Mutex<DownloadManager>);
|
||||
|
||||
@@ -596,6 +600,10 @@ pub(crate) async fn queue_album_tracks(
|
||||
/// TRACES: UR-018, UR-055 | DR-173 | UT-170
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
// Three of the eight arguments are Tauri `State<'_, _>` injections plus the
|
||||
// `AppHandle`, not caller input. Folding the rest into a struct would change the
|
||||
// IPC contract and the generated TypeScript for no readability gain.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn download_album(
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
repository: State<'_, crate::commands::repository::RepositoryManagerWrapper>,
|
||||
@@ -807,7 +815,7 @@ pub async fn download_series(
|
||||
vec![QueryParam::String(series_id)],
|
||||
);
|
||||
|
||||
let episodes: Vec<(String, String, Option<String>, Option<i32>, Option<i32>)> = db_service
|
||||
let episodes: Vec<EpisodeRow> = db_service
|
||||
.query_many(episodes_query, |row| {
|
||||
Ok((
|
||||
row.get(0)?,
|
||||
@@ -912,6 +920,10 @@ pub async fn download_series(
|
||||
/// Queue all episodes of a specific season for download
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
// One of the eight arguments is a Tauri `State<'_, _>` injection; the rest are
|
||||
// the season's identifying fields. Folding them into a struct would change the
|
||||
// IPC contract and the generated TypeScript for no readability gain.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn download_season(
|
||||
db: State<'_, DatabaseWrapper>,
|
||||
season_id: String,
|
||||
@@ -2307,7 +2319,7 @@ pub async fn delete_downloads_under(
|
||||
)";
|
||||
|
||||
let file_query = Query::with_params(
|
||||
&format!("SELECT d.file_path FROM downloads d WHERE {SCOPE}"),
|
||||
format!("SELECT d.file_path FROM downloads d WHERE {SCOPE}"),
|
||||
vec![
|
||||
QueryParam::String(user_id.clone()),
|
||||
QueryParam::String(item_id.clone()),
|
||||
@@ -2323,7 +2335,7 @@ pub async fn delete_downloads_under(
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let delete_query = Query::with_params(
|
||||
&format!("DELETE FROM downloads WHERE id IN (SELECT d.id FROM downloads d WHERE {SCOPE})"),
|
||||
format!("DELETE FROM downloads WHERE id IN (SELECT d.id FROM downloads d WHERE {SCOPE})"),
|
||||
vec![
|
||||
QueryParam::String(user_id),
|
||||
QueryParam::String(item_id.clone()),
|
||||
|
||||
Reference in New Issue
Block a user