1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! Functions for formatting values.

use crate::utils::divmod;

/// Formats a number of seconds as a clock time, \[H:\]MM:SS and SSs.
pub fn interval(seconds: usize, human: bool) -> String {
    if human && seconds < 60 {
        return seconds.to_string() + "s";
    }

    let (minutes, seconds) = divmod(seconds, 60);
    let (hours, minutes) = divmod(minutes, 60);

    if hours == 0 {
        format!("{:02}:{:02}", minutes, seconds)
    } else {
        format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
    }
}

/// Formats a number (greater than unity) with SI order of magnitude prefixes.
pub fn size_of(num: f64, divisor: f64) -> String {
    let mut value = num;

    for i in ["", "K", "M", "G", "T", "P", "E", "Z"] {
        if value.abs() < 999.5 {
            if value.abs() < 99.95 {
                if value.abs() < 9.995 {
                    return format!("{:1.2}{}", value, i);
                }
                return format!("{:2.1}{}", value, i);
            }
            return format!("{:3.0}{}", value, i);
        }
        value /= divisor;
    }

    format!("{:3.1}Y", value)
}

/// Formats seconds as a clock time, SSs | MMmin | Hhr | Ddays.
pub fn time(seconds: f64) -> String {
    let mut value = seconds;

    for (d, i) in [(60., "s"), (60., "min"), (24., "hr")] {
        if value.abs() < d - 0.005 {
            return format!("{:1.2}{}", value, i);
        }

        value /= d;
    }

    format!("{:1.2}days", value)
}

// Intelligent scientific notation (.3g).
// pub fn format_num(n: usize) -> String {
//     let f = format!("{:.3g}", n)
//         .replace("+0", "+")
//         .replace("-0", "-");
//     let n = format!("{}", n).to_string();
//     return if f.len() < n.len() { f } else { n };
// }