dec_cryptor/
progress_utils.rs1use std::sync::atomic::{AtomicI32, Ordering};
2use std::io::Write;
3use std::time::Instant;
4
5const RESET: &str = "\u{001B}[0m";
7const BLUE: &str = "\u{001B}[94m";
8const PROGRESS_BAR_LENGTH: usize = 40;
9static LAST_PROGRESS: AtomicI32 = AtomicI32::new(-1);
10
11pub fn update_progress(total_read: u64, file_size: u64) {
13 let mut progress = (total_read * 100 / file_size) as i32;
15
16 if progress > 98 {
18 progress = 100;
19 }
20
21 if progress == LAST_PROGRESS.load(Ordering::Relaxed) {
23 return;
24 }
25
26 const KB_FACTOR: f64 = 1024.0;
28 const MB_FACTOR: f64 = 1024.0 * 1024.0;
29 const GB_FACTOR: f64 = 1024.0 * 1024.0 * 1024.0;
30
31 let mut unit = "B";
32 let mut total_units = file_size as f64;
33 let mut read_units = total_read as f64;
34
35 if file_size as f64 >= GB_FACTOR {
37 total_units = file_size as f64 / GB_FACTOR;
38 read_units = total_read as f64 / GB_FACTOR;
39 unit = "GB";
40 } else if file_size as f64 >= MB_FACTOR {
41 total_units = file_size as f64 / MB_FACTOR;
42 read_units = total_read as f64 / MB_FACTOR;
43 unit = "MB";
44 } else if file_size as f64 >= KB_FACTOR {
45 total_units = file_size as f64 / KB_FACTOR;
46 read_units = total_read as f64 / KB_FACTOR;
47 unit = "KB";
48 }
49
50 progress = progress.min(100).max(0);
52 LAST_PROGRESS.store(progress, Ordering::Relaxed);
53
54 let filled_length = ((progress as f64 / 100.0) * PROGRESS_BAR_LENGTH as f64) as usize;
56
57 let mut progress_bar = String::with_capacity(100); progress_bar.push('[');
60
61 for i in 1..PROGRESS_BAR_LENGTH {
62 if i < filled_length {
63 progress_bar.push_str(&format!("{}#", BLUE));
64 } else if i == filled_length {
65 if progress < 100 {
66 progress_bar.push_str(&format!("{}>", BLUE));
67 } else {
68 progress_bar.push_str(&format!("{}#{}", BLUE, RESET));
69 }
70 } else {
71 progress_bar.push_str(&format!("{}-", RESET));
72 }
73 }
74
75 progress_bar.push_str(&format!("] {}%", progress));
76
77 print!("\r{}", progress_bar);
79 if progress < 98 {
80 print!("\t {:.2} : {:.2} {}", read_units, total_units, unit);
81 } else {
82 print!("\t {:.2} : {:.2} {}", total_units, total_units, unit);
83 }
84 std::io::stdout().flush().unwrap();
85
86 if progress == 100 {
88 println!();
89 }
90}
91
92pub fn format_duration(duration: std::time::Duration) -> String {
94 let total_secs = duration.as_secs();
95 let hours = total_secs / 3600;
96 let minutes = (total_secs % 3600) / 60;
97 let seconds = total_secs % 60;
98 let millis = duration.subsec_millis();
99
100 if hours > 0 {
101 format!("{}h {}m {}s", hours, minutes, seconds)
102 } else if minutes > 0 {
103 format!("{}m {}s", minutes, seconds)
104 } else {
105 format!("{}.{:03}s", seconds, millis)
106 }
107}
108
109pub fn start_timer() -> Instant {
111 Instant::now()
112}