runnerd_core/api/
units.rs1pub fn duration(seconds: u64) -> String {
8 match seconds {
9 0..60 => format!("{seconds}s"),
10 60..3600 => format!("{}m {:02}s", seconds / 60, seconds % 60),
11 3600..86_400 => format!("{}h {:02}m", seconds / 3600, seconds % 3600 / 60),
12 _ => format!("{}d {}h", seconds / 86_400, seconds % 86_400 / 3600),
13 }
14}
15
16pub fn ago(at: u64, now: u64) -> String {
18 match now.saturating_sub(at) {
19 0..10 => "just now".to_owned(),
20 seconds => format!("{} ago", duration(seconds)),
21 }
22}
23
24pub fn cpu_time(milliseconds: u64) -> String {
26 if milliseconds < 60_000 {
27 let tenths = (milliseconds + 50) / 100;
28 format!("{}.{}s", tenths / 10, tenths % 10)
29 } else {
30 duration(milliseconds / 1000)
31 }
32}
33
34pub fn cores_used(millicores: u64) -> String {
36 let hundredths = millicores.div_ceil(10);
37 let (whole, part) = (hundredths / 100, hundredths % 100);
38 if part == 0 {
39 whole.to_string()
40 } else if part.is_multiple_of(10) {
41 format!("{whole}.{}", part / 10)
42 } else {
43 format!("{whole}.{part:02}")
44 }
45}
46
47pub fn in_cores(millicores: u64) -> String {
49 match cores_used(millicores).as_str() {
50 "1" => "1 core".to_owned(),
51 number => format!("{number} cores"),
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn a_duration_reads_like_a_stopwatch_in_every_client() {
61 assert_eq!(duration(9), "9s");
62 assert_eq!(duration(72), "1m 12s");
63 assert_eq!(duration(3909), "1h 05m");
64 assert_eq!(duration(3 * 86_400 + 4 * 3600), "3d 4h");
65 }
66
67 #[test]
68 fn an_age_is_the_duration_since() {
69 assert_eq!(ago(100, 105), "just now");
70 assert_eq!(ago(0, 3909), "1h 05m ago");
71 assert_eq!(
72 ago(200, 100),
73 "just now",
74 "a time ahead of the clock is now"
75 );
76 }
77
78 #[test]
79 fn cpu_time_keeps_work_under_a_second() {
80 assert_eq!(cpu_time(4600), "4.6s");
81 assert_eq!(cpu_time(600), "0.6s");
82 assert_eq!(cpu_time(125_000), "2m 05s");
83 }
84
85 #[test]
86 fn cores_in_use_never_read_as_none() {
87 assert_eq!(cores_used(1), "0.01");
88 assert_eq!(cores_used(250), "0.25");
89 assert_eq!(cores_used(1500), "1.5");
90 assert_eq!(cores_used(12_000), "12");
91 assert_eq!(cores_used(0), "0");
92 assert_eq!(in_cores(1000), "1 core");
93 assert_eq!(in_cores(1250), "1.25 cores");
94 }
95}