Skip to main content

max / audiofiles

lint: deny clippy::unwrap_used in audiofiles-core (completes ratchet) Final crate in the deny(unwrap_used) ratchet; every audiofiles crate now carries #![cfg_attr(not(test), deny(clippy::unwrap_used))]. Five production sites, all argmin/argmax or peek on provably-non-empty collections, given justification via .expect(): - analysis/cluster.rs (x4): min_by/max_by over points (non-empty by caller) and 0..k (k >= 1; zero-k returns early), plus the medoid min_by over the non-empty idxs (empty clusters skipped). - vp_tree.rs: heap.peek() inside `heap.len() == k`, where k >= 1 is enforced at the public search entry (empty/k==0 returns early before recursion). 640 core tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-11 17:24 UTC
Commit: 3668768298945e8fead38025e843758aa6823ab6
Parent: 438450e
3 files changed, +10 insertions, -5 deletions
@@ -109,7 +109,7 @@ fn init_centroids(points: &[Vec<f64>], k: usize) -> Vec<Vec<f64>> {
109 109
110 110 let first = (0..points.len())
111 111 .min_by(|&a, &b| sq_dist(&points[a], &mean).total_cmp(&sq_dist(&points[b], &mean)))
112 - .unwrap();
112 + .expect("points is non-empty (guaranteed by caller)");
113 113
114 114 let mut centroids = vec![points[first].clone()];
115 115 let mut min_d: Vec<f64> = points.iter().map(|p| sq_dist(p, &points[first])).collect();
@@ -117,7 +117,7 @@ fn init_centroids(points: &[Vec<f64>], k: usize) -> Vec<Vec<f64>> {
117 117 while centroids.len() < k {
118 118 let next = (0..points.len())
119 119 .max_by(|&a, &b| min_d[a].total_cmp(&min_d[b]))
120 - .unwrap();
120 + .expect("points is non-empty (guaranteed by caller)");
121 121 centroids.push(points[next].clone());
122 122 for (i, p) in points.iter().enumerate() {
123 123 min_d[i] = min_d[i].min(sq_dist(p, &points[next]));
@@ -150,7 +150,7 @@ pub fn cluster_library(db: &Database, k: usize, max_iters: usize) -> Result<Clus
150 150 for (i, p) in points.iter().enumerate() {
151 151 let best = (0..k)
152 152 .min_by(|&a, &b| sq_dist(p, &centroids[a]).total_cmp(&sq_dist(p, &centroids[b])))
153 - .unwrap();
153 + .expect("k >= 1 (empty/zero-k inputs return early)");
154 154 if best != assign[i] {
155 155 assign[i] = best;
156 156 changed = true;
@@ -194,7 +194,7 @@ pub fn cluster_library(db: &Database, k: usize, max_iters: usize) -> Result<Clus
194 194 .min_by(|&&a, &&b| {
195 195 sq_dist(&points[a], &centroids[c]).total_cmp(&sq_dist(&points[b], &centroids[c]))
196 196 })
197 - .unwrap();
197 + .expect("idxs is non-empty (empty clusters are skipped above)");
198 198 clusters.push(Cluster {
199 199 id: c,
200 200 medoid_hash: hashes[medoid].clone(),
@@ -34,6 +34,11 @@
34 34 //! - [`error`] — Unified error type ([`error::CoreError`]) and shared utilities
35 35 //! - [`util`] — Path/file helpers and audio extension whitelist
36 36
37 + // Completes the deny(unwrap_used) ratchet across the audiofiles workspace.
38 + // Forbid bare unwrap in production code; tests opt out. `expect` with a
39 + // justification stays allowed for documented invariants.
40 + #![cfg_attr(not(test), deny(clippy::unwrap_used))]
41 +
37 42 pub mod analysis;
38 43 pub mod collections;
39 44 pub mod db;
@@ -292,7 +292,7 @@ fn search_nearest<T>(
292 292 heap.pop();
293 293 }
294 294 if heap.len() == k {
295 - *tau = heap.peek().unwrap().distance;
295 + *tau = heap.peek().expect("heap holds k >= 1 entries here").distance;
296 296 }
297 297 }
298 298