1use std::sync::atomic::{AtomicU64, Ordering};
3use std::sync::Arc;
4use std::time::Duration;
5
6use sysinfo::{CpuRefreshKind, RefreshKind, System, MINIMUM_CPU_UPDATE_INTERVAL};
7use tokio::time::sleep;
8
9fn format_with_commas(num: u64) -> String {
11 let s = num.to_string();
12 let mut result = String::new();
13 let mut count = 0;
14
15 for c in s.chars().rev() {
16 if count == 3 {
17 result.insert(0, ',');
18 count = 0;
19 }
20 result.insert(0, c);
21 count += 1;
22 }
23 result
24}
25
26pub async fn show_progress(generated: Arc<AtomicU64>, total: u64) {
27 let mut sys =
28 System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::everything()));
29
30 sys.refresh_cpu_usage();
32 sleep(MINIMUM_CPU_UPDATE_INTERVAL).await;
33 sys.refresh_cpu_usage();
34
35 let bar_width = 40;
36
37 loop {
38 let gen = generated.load(Ordering::SeqCst).min(total);
39 let percent = ((gen as f64) / (total as f64)) * 100.0;
40 let filled = ((percent / 100.0) * (bar_width as f64)).round() as usize;
41
42 let formatted_pos = format_with_commas(gen);
43 let formatted_len = format_with_commas(total);
44
45 let bar = format!(
46 "\x1B[32m{}\x1B[0m{}",
47 "█".repeat(filled),
48 "-".repeat(bar_width - filled)
49 );
50
51 sys.refresh_cpu_usage();
53 sys.refresh_memory();
54
55 let avg_cpu = if sys.cpus().is_empty() {
56 0.0
57 } else {
58 sys.cpus().iter().map(|c| c.cpu_usage()).sum::<f32>() / (sys.cpus().len() as f32)
59 };
60 let ram_percent = if sys.total_memory() == 0 {
61 0.0
62 } else {
63 ((sys.used_memory() as f64) / (sys.total_memory() as f64)) * 100.0
64 };
65
66 print!("\x1B[2F\x1B[2K"); println!(
69 "🎁 {} {:3.0}% | {} / {}",
70 bar, percent, formatted_pos, formatted_len
71 );
72 println!(" CPU:{:5.1}% | RAM:{:5.1}%", avg_cpu, ram_percent);
73
74 if gen >= total {
75 print!("\x1B[1F\x1B[2K");
77 print!("\x1B[1F\x1B[2K");
78 println!(
79 "🎁 \x1B[32m{}\x1B[0m 100% | {} / {}",
80 "█".repeat(bar_width),
81 formatted_len,
82 formatted_len
83 );
84 break;
85 }
86
87 sleep(Duration::from_millis(250)).await;
88 }
89}