pineapple_core/ut/
track.rs

1// Copyright (c) 2025, Tom Ouellette
2// Licensed under the BSD 3-Clause License
3
4use chrono;
5use colored::*;
6use kdam::{Bar, tqdm};
7
8/// A basic progress bar for tracking iterations
9pub fn progress_bar(n: usize, desc: &str, verbose: bool) -> Bar {
10    if !verbose {
11        return tqdm!(disable = true);
12    }
13
14    let pb = tqdm!(
15        total = n,
16        force_refresh = false,
17        desc = progress_timestamp(desc),
18        bar_format =
19            "{desc suffix=' '}[{percentage:.0}%] ({rate:.1}/s, eta: {remaining human=true})"
20    );
21    pb
22}
23
24/// A progress bar with a standardized timestamp for tracking time
25pub fn progress_timestamp(desc: &str) -> String {
26    let time = chrono::Local::now();
27    let ymd = time.format("%Y-%m-%dT").to_string();
28    let ymd = &ymd[..ymd.len() - 1];
29    let hms = time.format("%H:%M:%S").to_string();
30    let time = format!("{} | {}", ymd, hms);
31
32    format!(
33        "{} {} {} {} {} {}",
34        "[".bold(),
35        time,
36        "|".bold(),
37        "pineapple".truecolor(103, 194, 69).bold(),
38        "]".bold(),
39        desc,
40    )
41}
42
43/// Print timestamped statements to console
44pub fn progress_log(desc: &str, verbose: bool) {
45    if !verbose {
46        return;
47    }
48
49    println!("{}", progress_timestamp(desc));
50}
51
52/// Format numbers to readaable thousands format
53pub fn thousands_format<T>(number: T) -> String
54where
55    T: std::fmt::Display,
56{
57    let number = number.to_string();
58    if number.len() > 4 {
59        number
60            .as_bytes()
61            .rchunks(3)
62            .rev()
63            .map(std::str::from_utf8)
64            .collect::<Result<Vec<&str>, _>>()
65            .unwrap()
66            .join(",")
67    } else {
68        number.to_string()
69    }
70}