dm_database_sqllog2db/tui/
app.rs1#[cfg(feature = "tui")]
2use super::progress::ProgressTracker;
3#[cfg(feature = "tui")]
4use std::time::Instant;
5
6#[cfg(feature = "tui")]
8#[derive(Debug, Clone)]
9pub struct TuiApp {
10 pub current_file_index: usize,
12 pub total_files: usize,
14 pub current_file_name: String,
16 pub exported_records: usize,
18 pub error_records: usize,
20 pub start_time: Option<Instant>,
22 pub is_finished: bool,
24 pub exporter_name: String,
26 #[cfg_attr(feature = "tui", allow(dead_code))]
28 progress_tracker: Option<ProgressTracker>,
29}
30
31#[cfg(feature = "tui")]
32impl TuiApp {
33 #[must_use]
34 pub fn new(total_files: usize, exporter_name: String) -> Self {
35 Self {
36 current_file_index: 0,
37 total_files,
38 current_file_name: String::new(),
39 exported_records: 0,
40 error_records: 0,
41 start_time: None,
42 is_finished: false,
43 exporter_name,
44 progress_tracker: None,
45 }
46 }
47
48 #[must_use]
49 pub fn with_progress_tracker(mut self, tracker: ProgressTracker) -> Self {
50 self.progress_tracker = Some(tracker);
51 self
52 }
53
54 pub fn start(&mut self) {
55 self.start_time = Some(Instant::now());
56 }
57
58 pub fn set_file(&mut self, index: usize, name: String) {
59 self.current_file_index = index;
60 self.current_file_name = name;
61 }
62
63 pub fn add_records(&mut self, count: usize) {
64 self.exported_records += count;
65 }
66
67 pub fn add_errors(&mut self, count: usize) {
68 self.error_records += count;
69 }
70
71 pub fn finish(&mut self) {
72 self.is_finished = true;
73 }
74
75 #[must_use]
76 pub fn progress_percent(&self) -> u16 {
77 if self.total_files == 0 {
78 return 0;
79 }
80
81 let scaled = self.current_file_index.saturating_mul(100) / self.total_files;
82 u16::try_from(scaled.min(100)).unwrap_or(100)
83 }
84
85 #[must_use]
86 pub fn elapsed_secs(&self) -> f64 {
87 self.start_time.map_or(0.0, |t| t.elapsed().as_secs_f64())
88 }
89
90 #[must_use]
91 pub fn throughput(&self) -> u64 {
92 let elapsed_ms = self.start_time.map_or(0, |t| t.elapsed().as_millis());
93
94 if elapsed_ms > 0 && self.exported_records > 0 {
95 let per_sec = (self.exported_records as u128 * 1_000) / elapsed_ms;
96 u64::try_from(per_sec).unwrap_or(u64::MAX)
97 } else {
98 0
99 }
100 }
101}