Fix all cargo clippy warnings across the workspace
Some checks failed
check / check (push) Failing after 53s

Removes genuinely dead code (unused import, no-op cast, an unused
PendingGrab accessor, and TmdbClient's TV-search methods now that TVDB
fully covers that path), tightens len()>0 checks to is_empty(), swaps
two fixed-size test vec!s for arrays, restructures a match to avoid an
unnecessary unwrap_err, fixes doc-comment list indentation, and hoists
a locked-connection call out of a match scrutinee. Struct fields/enum
variants that are still meaningful but not read by current callers
(TorrentInfo::save_path, GrabCycleStats::items_seen, X1337 fallback
route, BacklogCandidate::path) get #[allow(dead_code)] rather than
deletion, same for the two 8-argument functions (too_many_arguments).
This commit is contained in:
Breadway 2026-08-06 08:51:07 +08:00
parent 471ca884a6
commit 5543485976
9 changed files with 32 additions and 106 deletions

View file

@ -99,14 +99,6 @@ impl PendingGrab {
PendingGrab::Movie { .. } | PendingGrab::SeasonPack { .. } => None,
}
}
fn root_folder(&self) -> &str {
match self {
PendingGrab::Episode { root_folder, .. }
| PendingGrab::Movie { root_folder, .. }
| PendingGrab::SeasonPack { root_folder, .. } => root_folder,
}
}
}
/// Three separate queries (rather than one `LEFT JOIN episode`) because a
@ -1615,7 +1607,7 @@ impl StaleFile {
/// later step (free-space check, the actual move) fails, so a failed
/// import never leaves neither the old file nor the new one behind.
fn restore(&self) {
if self.parked_at.as_os_str().len() > 0 {
if !self.parked_at.as_os_str().is_empty() {
std::fs::rename(&self.parked_at, &self.restore_to).ok();
}
}
@ -1909,7 +1901,7 @@ fn import_one(
if let Some(row_id) = stale.row_id {
conn.execute("DELETE FROM episode_file WHERE id = ?1", params![row_id])?;
}
if stale.parked_at.as_os_str().len() > 0 {
if !stale.parked_at.as_os_str().is_empty() {
std::fs::remove_file(&stale.parked_at).ok();
}
}
@ -2309,7 +2301,7 @@ fn import_season_pack_file(
if let Some(row_id) = stale.row_id {
conn.execute("DELETE FROM episode_file WHERE id = ?1", params![row_id])?;
}
if stale.parked_at.as_os_str().len() > 0 {
if !stale.parked_at.as_os_str().is_empty() {
std::fs::remove_file(&stale.parked_at).ok();
}
}

View file

@ -633,10 +633,11 @@ async fn background_loop(
// repaired (a rename or an in-place transcode) gets re-probed
// immediately rather than waiting for its own turn a full
// interval later.
match {
let probe_result = {
let conn = conn.lock().await;
importer::probe_library(&conn)
} {
};
match probe_result {
Ok(report) if report.probed > 0 || report.failed > 0 => {
info!(?report, "media probe sweep complete");
}

View file

@ -41,6 +41,7 @@ pub struct EpisodeInfo {
/// `MutexGuard` across an `.await` point — this convenience wrapper is only
/// safe for callers with an owned, unshared `Connection` (e.g. the debug
/// CLI commands).
#[allow(clippy::too_many_arguments)]
pub async fn add_series(
conn: &Connection,
tvdb: &tvdb::TvdbClient,

View file

@ -1,7 +1,7 @@
use anyhow::{Context, Result};
use serde::Deserialize;
use super::{EpisodeInfo, MovieSearchResult, SeriesSearchResult};
use super::MovieSearchResult;
pub struct TmdbClient {
bearer_token: String,
@ -22,44 +22,6 @@ impl TmdbClient {
}
}
pub async fn search_tv(&self, query: &str) -> Result<Vec<SeriesSearchResult>> {
#[derive(Deserialize)]
struct SearchResponse {
results: Vec<TvItem>,
}
#[derive(Deserialize)]
struct TvItem {
id: u64,
name: String,
first_air_date: Option<String>,
}
let resp: SearchResponse = self
.client
.get("https://api.themoviedb.org/3/search/tv")
.bearer_auth(&self.bearer_token)
.query(&[("query", query)])
.send()
.await
.context("tmdb tv search request failed")?
.error_for_status()
.context("tmdb tv search returned an error status")?
.json()
.await
.context("tmdb tv search response was not valid JSON")?;
Ok(resp
.results
.into_iter()
.map(|item| SeriesSearchResult {
external_id: item.id.to_string(),
name: item.name,
year: year_from_date(item.first_air_date.as_deref()),
aliases: Vec::new(),
})
.collect())
}
pub async fn search_movie(&self, query: &str) -> Result<Vec<MovieSearchResult>> {
#[derive(Deserialize)]
struct SearchResponse {
@ -96,48 +58,6 @@ impl TmdbClient {
})
.collect())
}
pub async fn tv_season_episodes(&self, tv_id: u64, season: u32) -> Result<Vec<EpisodeInfo>> {
#[derive(Deserialize)]
struct SeasonResponse {
#[serde(default)]
episodes: Vec<EpisodeItem>,
}
#[derive(Deserialize)]
struct EpisodeItem {
season_number: u32,
episode_number: u32,
name: Option<String>,
air_date: Option<String>,
}
let resp: SeasonResponse = self
.client
.get(format!(
"https://api.themoviedb.org/3/tv/{tv_id}/season/{season}"
))
.bearer_auth(&self.bearer_token)
.send()
.await
.context("tmdb season request failed")?
.error_for_status()
.context("tmdb season returned an error status")?
.json()
.await
.context("tmdb season response was not valid JSON")?;
Ok(resp
.episodes
.into_iter()
.map(|e| EpisodeInfo {
season_number: e.season_number,
episode_number: e.episode_number,
absolute_number: None,
title: e.name,
air_date: e.air_date,
})
.collect())
}
}
fn year_from_date(date: Option<&str>) -> Option<u32> {

View file

@ -1,4 +1,3 @@
use anyhow::Result;
use serde::Serialize;
#[derive(Serialize)]

View file

@ -69,6 +69,9 @@ pub struct TorrentInfo {
pub name: String,
pub state: String,
pub progress: f64,
// Not read internally today, but kept to mirror qBittorrent's actual API
// shape 1:1 — useful in `{:?}` debug logging and cheap to keep in sync.
#[allow(dead_code)]
pub save_path: String,
/// Full path to the torrent's content (file or directory root) —
/// qBittorrent resolves this for us, so importers don't need to guess

View file

@ -752,6 +752,10 @@ async fn grab_and_capture_hash(
#[derive(Debug, Default)]
pub struct GrabCycleStats {
// Only read via the derived `Debug` (the debug-grab-cycle CLI command
// prints the whole struct), which clippy's dead-code analysis doesn't
// credit as a read.
#[allow(dead_code)]
pub items_seen: usize,
pub new_items: usize,
pub grabbed: usize,
@ -840,8 +844,8 @@ pub async fn run_grab_cycle(
/// outright (TLS/connection error, not a slow response). Also
/// Cloudflare-fronted, so even if connectivity is restored it carries the
/// same risk profile 1337x does.
/// If revisiting either, re-verify connectivity first — this isn't a
/// permanent architectural decision, just what was true when checked.
/// If revisiting either, re-verify connectivity first — this isn't a
/// permanent architectural decision, just what was true when checked.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum SearchRoute {
/// Primary general-content (movies + non-anime TV) route — a JSON API,
@ -851,6 +855,7 @@ enum SearchRoute {
/// (not just "no relevant results") — the mirror-rotation/cooldown
/// machinery already built for it is real resilience worth keeping,
/// just no longer the first choice given TPB's better precision.
#[allow(dead_code)]
X1337,
NyaaSearch,
}
@ -1658,17 +1663,17 @@ pub async fn execute_search_targets(
// with, since dedup (`is_seen`/`mark_seen`) and grab records
// are keyed by source id — attributing a 1337x-sourced guid to
// TPB's source id would silently break dedup between the two.
let (fetch_result, result_source_id) =
if primary_result.is_err() && matches!(target.route, SearchRoute::Tpb) {
let (fetch_result, result_source_id) = match primary_result {
Err(e) if matches!(target.route, SearchRoute::Tpb) => {
tracing::warn!(
query = %target.query,
error = %primary_result.as_ref().unwrap_err(),
error = %e,
"TPB search failed, falling back to 1337x"
);
(scrape.fetch(Some(&target.query)).await, scrape_source_id)
} else {
(primary_result, primary_id)
};
}
other => (other, primary_id),
};
match fetch_result {
Ok(items) => {
@ -2821,7 +2826,7 @@ mod tests {
seeders: Some(500),
leechers: None,
};
let mut items = vec![episode.clone(), pack.clone()];
let mut items = [episode.clone(), pack.clone()];
items.sort_by_key(release_sort_key);
assert_eq!(items[0].guid, "pack");
assert_eq!(items[1].guid, "episode");
@ -2845,7 +2850,7 @@ mod tests {
seeders: Some(50),
leechers: None,
};
let mut items = vec![low.clone(), high.clone()];
let mut items = [low.clone(), high.clone()];
items.sort_by_key(release_sort_key);
assert_eq!(items[0].guid, "high");
assert_eq!(items[1].guid, "low");

View file

@ -337,6 +337,7 @@ enum EncodeOutcome {
/// original on most of a real backfill — regardless of how well-tuned the
/// rate control is, this is what makes "never keep a non-improvement" true
/// unconditionally.
#[allow(clippy::too_many_arguments)]
fn encode_and_verify(
input: PathBuf,
job_id: i64,
@ -726,6 +727,10 @@ pub fn find_oversized_av1_candidates(conn: &Connection, cfg: &TranscodeConfig) -
pub struct BacklogCandidate {
pub episode_file_id: i64,
// Not read by current callers (they only need episode_file_id to look up
// the row again), but cheap to carry along for future logging/debugging
// of which file a candidate refers to.
#[allow(dead_code)]
pub path: String,
pub size_bytes: i64,
pub video_codec: Option<String>,