#[derive(Debug, Clone)]
pub enum DiffProgress {
Started { total: usize },
File { path: String, processed: usize, total: usize },
Sorting,
Done { total_files: usize },
}
pub trait ProgressSink: Send + Sync {
fn emit(&self, event: DiffProgress);
}
#[derive(Default)]
pub struct NullProgress;
impl ProgressSink for NullProgress {
fn emit(&self, _: DiffProgress) {}
}
pub struct ChannelProgress {
tx: std::sync::mpsc::Sender<DiffProgress>,
}
impl ChannelProgress {
pub fn new(tx: std::sync::mpsc::Sender<DiffProgress>) -> Self {
Self { tx }
}
}
impl ProgressSink for ChannelProgress {
fn emit(&self, event: DiffProgress) {
let _ = self.tx.send(event);
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::mpsc;
#[test]
fn channel_progress_sends_events() {
let (tx, rx) = mpsc::channel();
let sink = ChannelProgress::new(tx);
sink.emit(DiffProgress::Started { total: 10 });
sink.emit(DiffProgress::Done { total_files: 10 });
let events: Vec<_> = rx.try_iter().collect();
assert_eq!(events.len(), 2);
}
#[test]
fn null_progress_does_not_panic() {
let sink = NullProgress;
sink.emit(DiffProgress::Started { total: 0 });
sink.emit(DiffProgress::Sorting);
}
}