v0.13.16 — single Progress trait + PassProgress (RIP_DESIGN.md §16)
Pre-0.13.16 the rip API leaked internal mapfile concepts (pos,
bytes_good, work_done, bytes_pending, Finished/NonTrimmed) into per-pass
positional callbacks Fn(u64, u64, u64). Consumers reinvented the math
each time, and v0.13.15's UI bug surfaced exactly because of this —
autorip's web JS computed pct from bytes_good while the backend
computed from pos, silent drift, frozen UI bar.
This release replaces both Disc::copy::on_progress and
Disc::patch::on_progress callbacks with a single Progress trait +
PassProgress struct (new progress module).
pub struct PassProgress {
pub kind: PassKind, // Sweep | Trim {reverse} | Scrape {reverse} | Mux
pub work_done: u64,
pub work_total: u64,
pub bytes_good_total: u64,
pub bytes_total_disc: u64,
}
pub trait Progress {
fn report(&self, p: &PassProgress);
}
impl<F: Fn(&PassProgress)> Progress for F { ... } // closures work directly
CopyOptions::on_progress and PatchOptions::on_progress are renamed to
progress: Option<&dyn Progress>. Closure callers update trivially via
the blanket impl; struct callers gain a clean named-field shape with no
positional-arg confusion.
PassKind carries the semantic (sweep vs trim vs scrape vs mux) so
consumers can label phases without reinventing detection logic.
Disc::patch reports Trim {reverse} for retry passes with block_sectors
>= 2 and Scrape {reverse} when block_sectors == 1. Direction comes
through reverse: bool. Mux variant is reserved for v0.13.17 when the
mux pipeline emits progress.
Tests + clippy clean across all 4 crates.
This commit is contained in:
@@ -175,17 +175,25 @@ fn test_disc_copy_progress_callback_fires() {
|
||||
|
||||
let calls = Arc::new(AtomicU64::new(0));
|
||||
let last_bytes = Arc::new(AtomicU64::new(0));
|
||||
let calls_cb = calls.clone();
|
||||
let last_bytes_cb = last_bytes.clone();
|
||||
|
||||
let progress = move |bytes: u64, _pos: u64, _total: u64| {
|
||||
calls_cb.fetch_add(1, Ordering::Relaxed);
|
||||
last_bytes_cb.store(bytes, Ordering::Relaxed);
|
||||
struct CountingReporter {
|
||||
calls: Arc<AtomicU64>,
|
||||
last_bytes: Arc<AtomicU64>,
|
||||
}
|
||||
impl libfreemkv::progress::Progress for CountingReporter {
|
||||
fn report(&self, p: &libfreemkv::progress::PassProgress) {
|
||||
self.calls.fetch_add(1, Ordering::Relaxed);
|
||||
self.last_bytes.store(p.bytes_good_total, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
let reporter = CountingReporter {
|
||||
calls: calls.clone(),
|
||||
last_bytes: last_bytes.clone(),
|
||||
};
|
||||
|
||||
let opts = CopyOptions {
|
||||
decrypt: false,
|
||||
on_progress: Some(&progress),
|
||||
progress: Some(&reporter),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user