Files
Sylpheed/crates/sylpheed-formats/examples/validate_cues.rs
MechaCat02 ccd49ac31f fix(lint): clear the clippy gate across examples and tests
80 findings, not the 14 the first run showed -- clippy stops at the first
failing compilation unit, so `--keep-going` is what makes the list complete.

60 were machine-applicable (`cargo clippy --fix`). The rest by hand:

* five descending `sort_by` -> `sort_by_key(Reverse(..))`
* `chunks_exact(4)` on both sides of four zips, so the compared items stay
  `[u8; 4]` rather than one array against one slice
* three `type` aliases for the census maps and the captured-quad tuple
* `&PathBuf` -> `&Path` in two disc tests
* two range loops; one of them keeps `#[allow(needless_range_loop)]` with the
  reason -- the index is into a map's value, which changes each iteration
* the module doc list in `invert_capture` re-indented to markdown's rules
* `blit`'s eight arguments get `#[allow(too_many_arguments)]`, not a struct

One dead `let off = b.len();` in a `ratc` test is dropped rather than renamed.
The sibling test at :162 is the one that asserts an offset; if this one was
meant to as well, that is a test change and not a lint fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:42:41 +02:00

94 lines
3.2 KiB
Rust

use std::fs;
use std::io::{Read, Seek, SeekFrom};
use std::process::Command;
use sylpheed_formats::slb;
fn rg(disc: &str, g: u64, n: usize) -> Vec<u8> {
let mut segs = vec![];
let mut cum = 0u64;
for i in 0..5 {
let p = format!("{disc}/dat/sound.p{i:02}");
if let Ok(m) = fs::metadata(&p) {
segs.push((cum, m.len(), p));
cum += m.len();
}
}
let mut out = vec![];
let (mut need, mut pos) = (n, g);
for (base, len, path) in &segs {
if need == 0 || pos >= base + len || pos < *base {
continue;
}
let local = pos - base;
let take = need.min((len - local) as usize);
let mut f = fs::File::open(path).unwrap();
f.seek(SeekFrom::Start(local)).unwrap();
let mut b = vec![0u8; take];
f.read_exact(&mut b).unwrap();
out.extend_from_slice(&b);
need -= take;
pos += take as u64;
}
out
}
fn dur(w: &str) -> String {
let o = Command::new("ffprobe")
.args([
"-v",
"error",
"-show_entries",
"format=duration:stream=channels",
"-of",
"default=nw=1:nk=1",
w,
])
.output()
.unwrap();
String::from_utf8_lossy(&o.stdout).replace('\n', " ")
}
fn movdur(disc: &str, m: &str) -> String {
dur(&format!("{disc}/dat/movie/{m}"))
}
fn main() {
let disc = std::env::var("SYLPHEED_DISC").unwrap();
// descriptor trailer global offsets (from scan) => cue N data = [desc(N-1)..desc(N)]
// (id, end_off, movie)
let cues = [
(1600u32, 437044592u64, "ADV.wmv"),
(1601, 437345648, "RT01A.wmv"),
(1602, 437712240, "RT01B.wmv"),
(1603, 438080880, "RT01C_1.wmv"),
(1604, 438451568, "RT01C_2.wmv"),
(1605, 438789488, "RT02A.wmv"),
];
for k in 1..cues.len() {
let (id, end, mov) = cues[k];
let start = cues[k - 1].1;
let region = rg(&disc, start, (end - start) as usize + 12000); // +tail to include full data before next trailer
let riffs = slb::to_xma_riffs(&region);
let mut total = 0.0f32;
let mut parts = vec![];
for (j, r) in riffs.iter().enumerate() {
let xp = format!("/tmp/cue{id}_{j}.xma.wav");
let wp = format!("/tmp/cue{id}_{j}.wav");
fs::write(&xp, r).unwrap();
let _ = Command::new("ffmpeg")
.args(["-hide_banner", "-v", "error", "-y", "-i", &xp, &wp])
.status();
let d = dur(&wp);
parts.push(d.clone());
total += d
.split_whitespace()
.next()
.unwrap_or("0")
.parse::<f32>()
.unwrap_or(0.0);
}
// spanning?
let span_adv_end = 437547264u64;
let _spans = start < span_adv_end && end > span_adv_end || (start / 1_000 != end / 1_000);
println!("cue {id} ({mov}): region[{start}..{end}] {} bytes, {} riff(s), Σ={:.1}s | movie={} parts={:?}",
end-start, riffs.len(), total, movdur(&disc,mov), parts);
}
println!("\nWAVs at /tmp/cue16XX_*.wav (listen: RT01B=1602, RT01C_1=1603, RT01C_2=1604)");
}