duration_human/
display.rs

1use std::fmt::{Debug, Display};
2
3use crate::{DurationHuman, DurationHumanValidator};
4
5impl Display for DurationHumanValidator {
6    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7        f.write_fmt(format_args!(
8            "must be between {min} and {max}",
9            min = self.min,
10            max = self.max
11        ))
12    }
13}
14
15impl Debug for DurationHumanValidator {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.debug_struct("DurationHumanValidator")
18            .field("min", &self.min.to_string())
19            .field("default", &self.default.to_string())
20            .field("max", &self.max.to_string())
21            .finish()
22    }
23}
24
25impl Display for DurationHuman {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        let mut nanos: u64 = self.into();
28        if f.alternate() {
29            let durations: Vec<String> = [
30                (Self::CENTURY, " century", " centuries"),
31                (Self::YEAR, " year", " years"),
32                (Self::MONTH, " month", " months"),
33                (Self::WEEK, " week", " weeks"),
34                (Self::DAY, " day", " days"),
35                (Self::HOUR, "h", "h"),
36                (Self::MINUTE, "min", "min"),
37                (Self::SEC, "s", "s"),
38                (Self::MILLI_SEC, "ms", "ms"),
39                (Self::MICRO_SEC, "μs", "μs"),
40                (1, "ns", "ns"),
41            ]
42            .iter()
43            .filter_map(|(part_ms, unit_singular, unit_plural)| {
44                let part = nanos / part_ms;
45                nanos %= part_ms;
46                if part > 0 {
47                    Some(format!(
48                        "{}{}",
49                        part,
50                        if part > 1 { unit_plural } else { unit_singular }
51                    ))
52                } else {
53                    None
54                }
55            })
56            .collect();
57            f.write_str(durations.join(" ").as_str())
58        } else {
59            f.write_str(
60                match nanos {
61                    _ if nanos < Self::MICRO_SEC || nanos % Self::MICRO_SEC != 0 => {
62                        format!("{nanos}ns")
63                    }
64                    _ if nanos < Self::MILLI_SEC || nanos % Self::MILLI_SEC != 0 => {
65                        format!("{}μs", nanos / Self::MICRO_SEC)
66                    }
67                    _ if nanos < Self::SEC || nanos % Self::SEC != 0 => {
68                        format!("{}ms", nanos / Self::MILLI_SEC)
69                    }
70                    _ if nanos < Self::MINUTE || nanos % Self::MINUTE != 0 => {
71                        format!("{}s", nanos / Self::SEC)
72                    }
73                    _ if nanos < Self::HOUR || nanos % Self::HOUR != 0 => {
74                        format!("{}min", nanos / Self::MINUTE)
75                    }
76                    _ if nanos < Self::DAY || nanos % Self::DAY != 0 => {
77                        format!("{}h", nanos / Self::HOUR)
78                    }
79                    _ if nanos < Self::WEEK || nanos % Self::WEEK != 0 => {
80                        format!(
81                            "{} day{}",
82                            nanos / Self::DAY,
83                            if nanos / Self::DAY > 1 { "s" } else { "" }
84                        )
85                    }
86                    _ if nanos < Self::MONTH || nanos % Self::MONTH != 0 => {
87                        format!(
88                            "{} week{}",
89                            nanos / Self::WEEK,
90                            if nanos / Self::WEEK > 1 { "s" } else { "" }
91                        )
92                    }
93                    _ if nanos < Self::YEAR || nanos % Self::YEAR != 0 => format!(
94                        "{} month{}",
95                        nanos / Self::MONTH,
96                        if nanos / Self::YEAR > 1 { "s" } else { "" }
97                    ),
98                    _ if nanos < Self::CENTURY || nanos % Self::CENTURY != 0 => {
99                        format!(
100                            "{} year{}",
101                            nanos / Self::YEAR,
102                            if nanos / Self::YEAR > 1 { "s" } else { "" }
103                        )
104                    }
105                    _ => format!(
106                        "{} centur{}",
107                        nanos / Self::CENTURY,
108                        if nanos / Self::CENTURY > 1 {
109                            "ies"
110                        } else {
111                            "y"
112                        }
113                    ),
114                }
115                .as_str(),
116            )
117        }
118    }
119}