rusync 0.7.2

Minimalist rsync clone in Rust
Documentation
use std::sync::mpsc::Receiver;
use std::time::Instant;

use crate::progress::{Progress, ProgressInfo, ProgressMessage};
use crate::sync::Stats;

pub struct ProgressWorker {
    input: Receiver<ProgressMessage>,
    progress_info: Box<dyn ProgressInfo + Send>,
}

impl ProgressWorker {
    pub fn new(
        input: Receiver<ProgressMessage>,
        progress_info: Box<dyn ProgressInfo + Send>,
    ) -> ProgressWorker {
        ProgressWorker {
            input,
            progress_info,
        }
    }

    pub fn start(mut self) -> Stats {
        let mut stats = Stats::new();
        let mut file_done = 0;
        let mut current_file = String::from("");
        let mut index = 0;
        let mut total_done = 0;
        let now = Instant::now();
        stats.start();
        for progress in self.input.iter() {
            match progress {
                ProgressMessage::Todo {
                    num_files,
                    total_size,
                } => {
                    stats.num_files = num_files;
                    stats.total_size = total_size;
                }
                ProgressMessage::StartSync(x) => {
                    self.progress_info.new_file(&x);
                    current_file = x;
                    index += 1;
                }
                ProgressMessage::DoneSyncing(x) => {
                    self.progress_info.done_syncing();
                    stats.add_outcome(&x);
                    file_done = 0;
                }
                ProgressMessage::SyncError { entry, details } => {
                    self.progress_info.error(&entry, &details);
                    stats.add_error();
                }
                ProgressMessage::Syncing { done, size, .. } => {
                    file_done += done;
                    total_done += done;
                    let elapsed = now.elapsed().as_secs() as usize;
                    let eta = ((elapsed * stats.total_size) / total_done) - elapsed;
                    let detailed_progress = Progress {
                        file_done,
                        file_size: size,
                        total_done,
                        total_size: stats.total_size,
                        index,
                        num_files: stats.num_files as usize,
                        current_file: current_file.clone(),
                        eta,
                    };
                    self.progress_info.progress(&detailed_progress);
                }
            }
        }
        stats.stop();
        self.progress_info.end(&stats);
        stats
    }
}