turbo_maker/
progress.rs

1// progress.rs
2use 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
9// Function to format number with commas
10fn 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    // CPU warm-up
31    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        // updating system metrics
52        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        // redraw (clear 2 lines)
67        print!("\x1B[2F\x1B[2K"); // cursor 2 lines up, clear
68        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            // final: clear CPU/RAM lines and leave only the bar
76            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}