Skip to main content

worktree_setup_copy/
progress.rs

1//! Progress tracking for copy operations.
2
3#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
4#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
5#![allow(clippy::multiple_crate_versions)]
6
7use std::sync::Arc;
8use std::sync::atomic::{AtomicU64, Ordering};
9
10/// Progress information for a copy operation.
11#[derive(Debug, Clone)]
12pub struct CopyProgress {
13    /// Total number of files to copy.
14    pub files_total: u64,
15    /// Number of files copied so far.
16    pub files_copied: u64,
17    /// Current file being copied (if any).
18    pub current_file: Option<String>,
19}
20
21impl CopyProgress {
22    /// Create a new progress report.
23    #[must_use]
24    pub fn new(files_total: u64, files_copied: u64, current_file: Option<String>) -> Self {
25        Self {
26            files_total,
27            files_copied,
28            current_file,
29        }
30    }
31
32    /// Calculate progress as a percentage (0.0 to 100.0).
33    #[must_use]
34    pub fn percentage(&self) -> f64 {
35        if self.files_total == 0 {
36            100.0
37        } else {
38            (self.files_copied as f64 / self.files_total as f64) * 100.0
39        }
40    }
41}
42
43/// Thread-safe progress tracker using atomics.
44#[derive(Debug)]
45pub struct ProgressTracker {
46    files_total: AtomicU64,
47    files_copied: AtomicU64,
48}
49
50impl ProgressTracker {
51    /// Create a new progress tracker.
52    #[must_use]
53    pub fn new() -> Arc<Self> {
54        Arc::new(Self {
55            files_total: AtomicU64::new(0),
56            files_copied: AtomicU64::new(0),
57        })
58    }
59
60    /// Set the total number of files.
61    pub fn set_total(&self, total: u64) {
62        self.files_total.store(total, Ordering::SeqCst);
63    }
64
65    /// Increment the copied count by 1.
66    pub fn increment_copied(&self) {
67        self.files_copied.fetch_add(1, Ordering::SeqCst);
68    }
69
70    /// Get the current total.
71    #[must_use]
72    pub fn total(&self) -> u64 {
73        self.files_total.load(Ordering::SeqCst)
74    }
75
76    /// Get the current copied count.
77    #[must_use]
78    pub fn copied(&self) -> u64 {
79        self.files_copied.load(Ordering::SeqCst)
80    }
81
82    /// Get a progress snapshot.
83    #[must_use]
84    pub fn snapshot(&self, current_file: Option<String>) -> CopyProgress {
85        CopyProgress::new(self.total(), self.copied(), current_file)
86    }
87}
88
89impl Default for ProgressTracker {
90    fn default() -> Self {
91        Self {
92            files_total: AtomicU64::new(0),
93            files_copied: AtomicU64::new(0),
94        }
95    }
96}