gravityfile_scan/
progress.rs

1//! Scan progress reporting.
2
3use std::path::PathBuf;
4use std::time::{Duration, Instant};
5
6/// Progress information during a scan.
7#[derive(Debug, Clone)]
8pub struct ScanProgress {
9    /// Number of files scanned so far.
10    pub files_scanned: u64,
11    /// Number of directories scanned so far.
12    pub dirs_scanned: u64,
13    /// Total bytes scanned so far.
14    pub bytes_scanned: u64,
15    /// Current path being scanned.
16    pub current_path: PathBuf,
17    /// Number of errors/warnings encountered.
18    pub errors_count: u64,
19    /// Time elapsed since scan started.
20    pub elapsed: Duration,
21}
22
23impl ScanProgress {
24    /// Create initial progress state.
25    pub fn new() -> Self {
26        Self {
27            files_scanned: 0,
28            dirs_scanned: 0,
29            bytes_scanned: 0,
30            current_path: PathBuf::new(),
31            errors_count: 0,
32            elapsed: Duration::ZERO,
33        }
34    }
35
36    /// Calculate scan rate in files per second.
37    pub fn files_per_second(&self) -> f64 {
38        if self.elapsed.as_secs_f64() > 0.0 {
39            self.files_scanned as f64 / self.elapsed.as_secs_f64()
40        } else {
41            0.0
42        }
43    }
44
45    /// Calculate scan rate in bytes per second.
46    pub fn bytes_per_second(&self) -> f64 {
47        if self.elapsed.as_secs_f64() > 0.0 {
48            self.bytes_scanned as f64 / self.elapsed.as_secs_f64()
49        } else {
50            0.0
51        }
52    }
53
54    /// Get total items scanned (files + dirs).
55    pub fn total_items(&self) -> u64 {
56        self.files_scanned + self.dirs_scanned
57    }
58}
59
60impl Default for ScanProgress {
61    fn default() -> Self {
62        Self::new()
63    }
64}
65
66/// Internal progress tracker with timing.
67/// Reserved for async progress reporting with tokio channels.
68#[allow(dead_code)]
69#[derive(Debug)]
70pub(crate) struct ProgressTracker {
71    start_time: Instant,
72    files_scanned: u64,
73    dirs_scanned: u64,
74    bytes_scanned: u64,
75    errors_count: u64,
76    current_path: PathBuf,
77}
78
79#[allow(dead_code)]
80impl ProgressTracker {
81    pub fn new() -> Self {
82        Self {
83            start_time: Instant::now(),
84            files_scanned: 0,
85            dirs_scanned: 0,
86            bytes_scanned: 0,
87            errors_count: 0,
88            current_path: PathBuf::new(),
89        }
90    }
91
92    pub fn record_file(&mut self, size: u64) {
93        self.files_scanned += 1;
94        self.bytes_scanned += size;
95    }
96
97    pub fn record_dir(&mut self) {
98        self.dirs_scanned += 1;
99    }
100
101    pub fn record_error(&mut self) {
102        self.errors_count += 1;
103    }
104
105    pub fn set_current_path(&mut self, path: PathBuf) {
106        self.current_path = path;
107    }
108
109    pub fn snapshot(&self) -> ScanProgress {
110        ScanProgress {
111            files_scanned: self.files_scanned,
112            dirs_scanned: self.dirs_scanned,
113            bytes_scanned: self.bytes_scanned,
114            current_path: self.current_path.clone(),
115            errors_count: self.errors_count,
116            elapsed: self.start_time.elapsed(),
117        }
118    }
119}
120
121impl Default for ProgressTracker {
122    fn default() -> Self {
123        Self::new()
124    }
125}