timecalc/
formatter.rs

1use chrono::Duration;
2
3/// Format a [duration](chrono::Duration) into a [String].
4///
5/// ## Example
6/// ```
7/// use chrono::Duration;
8/// use timecalc::formatter::duration_to_str;
9///
10/// assert_eq!(duration_to_str(Duration::hours(1)), "1h");
11/// assert_eq!(duration_to_str(Duration::minutes(30)), "30m");
12/// assert_eq!(duration_to_str(Duration::hours(1) + Duration::minutes(30)), "1h 30m");
13/// ```
14pub fn duration_to_str(duration: Duration) -> String {
15    if duration == Duration::zero() {
16        return "0m".to_string();
17    }
18
19    let weeks = duration.num_weeks();
20    let days = duration.num_days() % 7;
21    let hours = duration.num_hours() % 24;
22    let minutes = duration.num_minutes() % 60;
23
24    let mut output = String::new();
25    if weeks != 0 {
26        output.push_str(&format!("{}w ", weeks));
27    }
28    if days != 0 {
29        output.push_str(&format!("{}d ", days));
30    }
31    if hours != 0 {
32        output.push_str(&format!("{}h ", hours));
33    }
34    if minutes != 0 {
35        output.push_str(&format!("{}m", minutes));
36    }
37
38    output.trim().to_string()
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    #[test]
45    fn test_duration_to_str() {
46        assert_eq!(
47            duration_to_str(
48                Duration::weeks(1) + Duration::days(2) + Duration::hours(3) + Duration::minutes(4)
49            ),
50            "1w 2d 3h 4m"
51        );
52        assert_eq!(
53            duration_to_str(Duration::weeks(1) + Duration::days(2) + Duration::hours(3)),
54            "1w 2d 3h"
55        );
56        assert_eq!(
57            duration_to_str(Duration::weeks(1) + Duration::days(2)),
58            "1w 2d"
59        );
60        assert_eq!(duration_to_str(Duration::weeks(1)), "1w");
61        assert_eq!(duration_to_str(Duration::days(2)), "2d");
62        assert_eq!(duration_to_str(Duration::hours(3)), "3h");
63        assert_eq!(duration_to_str(Duration::minutes(4)), "4m");
64        assert_eq!(
65            duration_to_str(Duration::days(1) - Duration::hours(1)),
66            "23h"
67        );
68        assert_eq!(duration_to_str(Duration::zero()), "0m");
69    }
70}