proto_types/duration/
formatting.rs

1#![allow(clippy::option_map_unit_fn)]
2use std::fmt::Display;
3
4use super::data::DurationData;
5use crate::Duration;
6
7/// Formats a duration in human readable form. (e.g. "2 days 15 hours 12 minutes and 15 seconds")
8impl Display for Duration {
9  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10    let DurationData {
11      months,
12      days,
13      hours,
14      minutes,
15      seconds,
16      is_negative,
17      ..
18    } = self.get_data();
19
20    let mut parts = Vec::new();
21
22    let sign = if is_negative { "- " } else { "" };
23
24    months.format_if_nonzero().map(|p| parts.push(p));
25    days.format_if_nonzero().map(|p| parts.push(p));
26    hours.format_if_nonzero().map(|p| parts.push(p));
27    minutes.format_if_nonzero().map(|p| parts.push(p));
28    seconds.format_if_nonzero().map(|p| parts.push(p));
29
30    if parts.is_empty() {
31      write!(f, "0 seconds")
32    } else {
33      let formatted_string = match parts.len() {
34        1 => parts.remove(0),
35        2 => format!("{}{} and {}", sign, parts[0], parts[1]),
36        _ => {
37          let last = parts.pop().unwrap();
38          format!("{}{} and {}", sign, parts.join(" "), last)
39        }
40      };
41
42      write!(f, "{}", formatted_string)
43    }
44  }
45}