1pub use borg_trace::{civil_from_days, days_from_civil};
8
9pub const DAY_MS: i64 = 24 * 60 * 60 * 1000;
12
13pub fn ago(ms: i64) -> String {
17 let s = (ms / 1000).max(0);
18 let day = DAY_MS / 1000;
19 match s {
20 0..60 => format!("{s}s"),
21 60..3600 => format!("{}m", s / 60),
22 _ if s < day => format!("{}h{:02}m", s / 3600, (s % 3600) / 60),
23 _ => format!("{}d", s / day),
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn a_day_is_a_day() {
33 assert_eq!(DAY_MS, 86_400_000);
34 }
35
36 #[test]
37 fn an_age_reads_in_its_largest_unit() {
38 assert_eq!(ago(-5_000), "0s");
39 assert_eq!(ago(59_999), "59s");
40 assert_eq!(ago(60_000), "1m");
41 assert_eq!(ago(3_599_999), "59m");
42 assert_eq!(ago(3_600_000), "1h00m");
43 assert_eq!(ago(3 * 3_600_000 + 5 * 60_000 + 59_000), "3h05m");
44 assert_eq!(ago(DAY_MS - 1), "23h59m");
45 assert_eq!(ago(DAY_MS), "1d");
46 assert_eq!(ago(7 * DAY_MS - 1), "6d");
47 assert!(ago(99 * DAY_MS).len() <= 6 && ago(DAY_MS - 1).len() <= 6, "fits a 6-wide column");
48 }
49
50 #[test]
51 fn the_calendar_is_reachable_here() {
52 assert_eq!(civil_from_days(days_from_civil(2026, 10, 28)), (2026, 10, 28));
53 }
54}