From d983985faa2884abf1860f64734d4b05e262c3f3 Mon Sep 17 00:00:00 2001 From: MattJackson <1085847+MattJackson@users.noreply.github.com> Date: Wed, 15 Apr 2026 04:09:56 +0000 Subject: [PATCH] Fix all clippy warnings: dead code, match patterns, type complexity, docs - Remove unused pes_buf field from M2tsStream and unused TS_PACKET/BD_TS_PACKET constants - Replace match-with-single-pattern with if let (3 instances in drive/mod.rs) - Replace match-can-be-? with ? operator for scsi::open call - Add type aliases PesSetup and MkvHeaderResult to reduce type complexity - Collapse identical if/else branches in tsmux.rs build_pes_header - Use RangeInclusive::contains instead of manual range checks - Make WriteSeek trait pub (was pub(crate) but leaked through pub fn) - Remove empty line after doc comment in disc.rs - Fix doc list item indentation in scsi/linux.rs (12 instances) --- src/drive/mod.rs | 42 +++++++++++++++--------------------------- src/mux/disc.rs | 1 - src/mux/m2ts.rs | 8 +++----- src/mux/mkvstream.rs | 4 +++- src/mux/mod.rs | 2 +- src/mux/tsmux.rs | 10 ++-------- src/scsi/linux.rs | 40 ++++++++++++++++++++-------------------- 7 files changed, 44 insertions(+), 63 deletions(-) diff --git a/src/drive/mod.rs b/src/drive/mod.rs index a1f0a05..2b623c2 100644 --- a/src/drive/mod.rs +++ b/src/drive/mod.rs @@ -428,21 +428,18 @@ impl Drive { ]; // Normal read - match self.scsi.as_mut().execute( + if let Ok(result) = self.scsi.as_mut().execute( &cdb, crate::scsi::DataDirection::FromDevice, buf, timeout_ms, ) { - Ok(result) => { - if self.recovery_bytes_remaining > 0 { - let bytes_read = count as u64 * 2048; - self.recovery_bytes_remaining = - self.recovery_bytes_remaining.saturating_sub(bytes_read); - if self.recovery_bytes_remaining == 0 { - self.set_speed(0xFFFF); - } + if self.recovery_bytes_remaining > 0 { + let bytes_read = count as u64 * 2048; + self.recovery_bytes_remaining = + self.recovery_bytes_remaining.saturating_sub(bytes_read); + if self.recovery_bytes_remaining == 0 { + self.set_speed(0xFFFF); } - return Ok(result.bytes_transferred); } - Err(_) => {} + return Ok(result.bytes_transferred); } // Phase 1: gentle — sleep 30s, retry. 5 times. @@ -451,14 +448,11 @@ impl Drive { for _ in 0..5 { std::thread::sleep(std::time::Duration::from_secs(30)); - match self.scsi.as_mut().execute( + if let Ok(result) = self.scsi.as_mut().execute( &cdb, crate::scsi::DataDirection::FromDevice, buf, 30_000, ) { - Ok(result) => { - self.recovery_bytes_remaining = RECOVERY_WINDOW; - return Ok(result.bytes_transferred); - } - Err(_) => {} + self.recovery_bytes_remaining = RECOVERY_WINDOW; + return Ok(result.bytes_transferred); } } @@ -467,10 +461,7 @@ impl Drive { std::thread::sleep(std::time::Duration::from_secs(5)); let _ = crate::scsi::reset(&device); std::thread::sleep(std::time::Duration::from_secs(5)); - self.scsi = match crate::scsi::open(&device) { - Ok(s) => s, - Err(e) => return Err(e), - }; + self.scsi = crate::scsi::open(&device)?; let _ = self.init(); let _ = self.wait_ready(); self.set_speed(0); @@ -479,14 +470,11 @@ impl Drive { for _ in 0..5 { std::thread::sleep(std::time::Duration::from_secs(30)); - match self.scsi.as_mut().execute( + if let Ok(result) = self.scsi.as_mut().execute( &cdb, crate::scsi::DataDirection::FromDevice, buf, 30_000, ) { - Ok(result) => { - self.recovery_bytes_remaining = RECOVERY_WINDOW; - return Ok(result.bytes_transferred); - } - Err(_) => {} + self.recovery_bytes_remaining = RECOVERY_WINDOW; + return Ok(result.bytes_transferred); } } diff --git a/src/mux/disc.rs b/src/mux/disc.rs index d176876..4e5b38c 100644 --- a/src/mux/disc.rs +++ b/src/mux/disc.rs @@ -166,7 +166,6 @@ impl DiscStream { } /// Set SCSI read timeout (default 30s). - fn new(drive: Drive, title: DiscTitle, mode: ReadMode, max_batch: u16) -> Self { // Set up PES demux from title stream PIDs let mut pids = Vec::new(); diff --git a/src/mux/m2ts.rs b/src/mux/m2ts.rs index fb5f7fb..5336565 100644 --- a/src/mux/m2ts.rs +++ b/src/mux/m2ts.rs @@ -7,6 +7,8 @@ use super::{meta, ts, IOStream, ReadSeek}; use crate::disc::{DiscTitle, Stream as DiscStream}; use std::io::{self, Read, Seek, SeekFrom, Write}; +type PesSetup = (Vec, Vec<(u16, Box)>, Vec<(u16, usize)>); + /// Size of initial scan buffer for PMT/stream detection. const SCAN_SIZE: usize = 1024 * 1024; @@ -32,7 +34,6 @@ pub struct M2tsStream { parsers: Vec<(u16, Box)>, pending_frames: std::collections::VecDeque, pid_to_track: Vec<(u16, usize)>, - pes_buf: Vec, pes_eof: bool, } @@ -51,12 +52,11 @@ impl M2tsStream { parsers: Vec::new(), pending_frames: std::collections::VecDeque::new(), pid_to_track: Vec::new(), - pes_buf: Vec::new(), pes_eof: false, } } - fn setup_pes(streams: &[DiscStream]) -> (Vec, Vec<(u16, Box)>, Vec<(u16, usize)>) { + fn setup_pes(streams: &[DiscStream]) -> PesSetup { let mut pids = Vec::new(); let mut parsers: Vec<(u16, Box)> = Vec::new(); let mut pid_to_track = Vec::new(); @@ -104,7 +104,6 @@ impl M2tsStream { parsers, pending_frames: std::collections::VecDeque::new(), pid_to_track, - pes_buf: vec![0u8; 192 * 1024], pes_eof: false, }); } @@ -144,7 +143,6 @@ impl M2tsStream { parsers, pending_frames: std::collections::VecDeque::new(), pid_to_track, - pes_buf: vec![0u8; 192 * 1024], pes_eof: false, }) } diff --git a/src/mux/mkvstream.rs b/src/mux/mkvstream.rs index 4073378..491fd86 100644 --- a/src/mux/mkvstream.rs +++ b/src/mux/mkvstream.rs @@ -8,6 +8,8 @@ use super::lookahead::{LookaheadBuffer, LookaheadState, DEFAULT_LOOKAHEAD_SIZE}; use super::mkv::{MkvMuxer, MkvTrack}; use super::ts::TsDemuxer; use super::{ebml, IOStream, ReadSeek, WriteSeek}; + +type MkvHeaderResult = io::Result<(crate::disc::DiscTitle, Vec<(u16, Vec)>)>; use crate::disc::*; use std::io::{self, Read, Seek, SeekFrom, Write}; @@ -462,7 +464,7 @@ fn write_pes( /// Returns (DiscTitle, codec_privates: Vec<(track_number, codec_private_bytes)>) fn parse_mkv_header( r: &mut (impl Read + Seek), -) -> io::Result<(DiscTitle, Vec<(u16, Vec)>)> { +) -> MkvHeaderResult { let mut title = String::new(); let mut duration_ms = 0.0f64; let mut ts_scale: u64 = 1_000_000; diff --git a/src/mux/mod.rs b/src/mux/mod.rs index 33e3d8f..3f0ad7c 100644 --- a/src/mux/mod.rs +++ b/src/mux/mod.rs @@ -79,5 +79,5 @@ pub trait IOStream: Read + Write { pub(crate) trait ReadSeek: Read + Seek {} impl ReadSeek for T {} -pub(crate) trait WriteSeek: Write + Seek {} +pub trait WriteSeek: Write + Seek {} impl WriteSeek for T {} diff --git a/src/mux/tsmux.rs b/src/mux/tsmux.rs index 126d9fa..412bd4d 100644 --- a/src/mux/tsmux.rs +++ b/src/mux/tsmux.rs @@ -8,8 +8,6 @@ use std::io::{self, Write}; const SYNC_BYTE: u8 = 0x47; const TS_PAYLOAD: usize = 184; -const TS_PACKET: usize = 188; -const BD_TS_PACKET: usize = 192; pub struct TsMuxer { writer: W, @@ -112,14 +110,10 @@ impl TsMuxer { /// Build a PES packet header for a BD stream. fn build_pes_header(pid: u16, pts_90k: u64, data_len: usize) -> Vec { // Determine stream_id from PID range - let stream_id: u8 = if pid >= 0x1011 && pid <= 0x101F { + let stream_id: u8 = if (0x1011..=0x101F).contains(&pid) { 0xE0 // video - } else if pid >= 0x1100 && pid <= 0x111F { - 0xBD // audio (private stream 1) - } else if pid >= 0x1200 && pid <= 0x121F { - 0xBD // PGS subtitle } else { - 0xBD // default + 0xBD // audio, PGS subtitle, or default (private stream 1) }; let pes_data_len = data_len + 8; // 3 header bytes + 5 PTS bytes + data diff --git a/src/scsi/linux.rs b/src/scsi/linux.rs index c2fd29c..b42e0d4 100644 --- a/src/scsi/linux.rs +++ b/src/scsi/linux.rs @@ -82,26 +82,26 @@ impl SgIoTransport { /// /// ## Sequence /// - /// 1. **open** — allocates kernel SG state for this fd - /// 2. **close** — triggers kernel cleanup: aborts any pending SG_IO - /// commands associated with this fd. The key operation — - /// the kernel's sg_release() cancels queued commands. - /// 3. **sleep 2s** — the drive firmware needs time to finish/abort whatever - /// it was doing when the previous process died. Without - /// this, the next command may block on drive-internal state. - /// 4. **open** — fresh fd with no stale commands in the kernel queue - /// 5. **unlock** — ALLOW MEDIUM REMOVAL (CDB 0x1E, prevent=0). Clears - /// any tray lock left by a killed process that never - /// ran its Drop/cleanup. - /// 6. **TUR** — TEST UNIT READY (CDB 0x00) with 3s timeout. If the - /// drive responds, it's in a good state. - /// 7. **escalate** — if TUR fails: - /// a. SG_SCSI_RESET (device level) — kernel sends a SCSI - /// bus reset to the device, clearing all firmware state. - /// b. STOP + START UNIT (CDB 0x1B) — power-cycles the - /// drive's logical unit, like pressing the eject button - /// and reinserting. - /// 8. **close** — release the fd. Drive is clean, nobody holds it. + /// 1. **open** — allocates kernel SG state for this fd + /// 2. **close** — triggers kernel cleanup: aborts any pending SG_IO + /// commands associated with this fd. The key operation — + /// the kernel's sg_release() cancels queued commands. + /// 3. **sleep 2s** — the drive firmware needs time to finish/abort whatever + /// it was doing when the previous process died. Without + /// this, the next command may block on drive-internal state. + /// 4. **open** — fresh fd with no stale commands in the kernel queue + /// 5. **unlock** — ALLOW MEDIUM REMOVAL (CDB 0x1E, prevent=0). Clears + /// any tray lock left by a killed process that never + /// ran its Drop/cleanup. + /// 6. **TUR** — TEST UNIT READY (CDB 0x00) with 3s timeout. If the + /// drive responds, it's in a good state. + /// 7. **escalate** — if TUR fails: + /// - SG_SCSI_RESET (device level) — kernel sends a SCSI + /// bus reset to the device, clearing all firmware state. + /// - STOP + START UNIT (CDB 0x1B) — power-cycles the + /// drive's logical unit, like pressing the eject button + /// and reinserting. + /// 8. **close** — release the fd. Drive is clean, nobody holds it. pub fn reset(device: &Path) -> Result<()> { let c_path = Self::to_c_path(device);