1use std::time::Duration;
2
3pub trait DurationExt {
34 fn seconds(self) -> Duration;
36 fn minutes(self) -> Duration;
38 fn hours(self) -> Duration;
40 fn milliseconds(self) -> Duration;
42 fn microseconds(self) -> Duration;
44 fn nanoseconds(self) -> Duration;
46}
47
48impl DurationExt for u64 {
50 fn seconds(self) -> Duration {
51 Duration::from_secs(self)
52 }
53
54 fn minutes(self) -> Duration {
55 let secs = self.checked_mul(60)
56 .expect(&format!("duration value {} minutes overflows u64 seconds capacity", self));
57 Duration::from_secs(secs)
58 }
59
60 fn hours(self) -> Duration {
61 let secs = self.checked_mul(3600)
62 .expect(&format!("duration value {} hours overflows u64 seconds capacity", self));
63 Duration::from_secs(secs)
64 }
65
66 fn milliseconds(self) -> Duration {
67 Duration::from_millis(self)
68 }
69
70 fn microseconds(self) -> Duration {
71 Duration::from_micros(self)
72 }
73
74 fn nanoseconds(self) -> Duration {
75 Duration::from_nanos(self)
76 }
77}
78
79impl DurationExt for u32 {
80 fn seconds(self) -> Duration {
81 Duration::from_secs(self as u64)
82 }
83
84 fn minutes(self) -> Duration {
86 (self as u64).minutes()
87 }
88
89 fn hours(self) -> Duration {
91 (self as u64).hours()
92 }
93
94 fn milliseconds(self) -> Duration {
95 Duration::from_millis(self as u64)
96 }
97
98 fn microseconds(self) -> Duration {
99 Duration::from_micros(self as u64)
100 }
101
102 fn nanoseconds(self) -> Duration {
103 Duration::from_nanos(self as u64)
104 }
105}
106
107impl DurationExt for i64 {
109 fn seconds(self) -> Duration {
110 assert!(self >= 0, "duration cannot be negative: got {} seconds", self);
111 Duration::from_secs(self as u64)
112 }
113
114 fn minutes(self) -> Duration {
115 assert!(self >= 0, "duration cannot be negative: got {} minutes", self);
116 (self as u64).minutes()
118 }
119
120 fn hours(self) -> Duration {
121 assert!(self >= 0, "duration cannot be negative: got {} hours", self);
122 (self as u64).hours()
124 }
125
126 fn milliseconds(self) -> Duration {
127 assert!(self >= 0, "duration cannot be negative: got {} milliseconds", self);
128 Duration::from_millis(self as u64)
129 }
130
131 fn microseconds(self) -> Duration {
132 assert!(self >= 0, "duration cannot be negative: got {} microseconds", self);
133 Duration::from_micros(self as u64)
134 }
135
136 fn nanoseconds(self) -> Duration {
137 assert!(self >= 0, "duration cannot be negative: got {} nanoseconds", self);
138 Duration::from_nanos(self as u64)
139 }
140}
141
142impl DurationExt for i32 {
143 fn seconds(self) -> Duration {
144 assert!(self >= 0, "duration cannot be negative: got {} seconds", self);
145 Duration::from_secs(self as u64)
146 }
147
148 fn minutes(self) -> Duration {
149 assert!(self >= 0, "duration cannot be negative: got {} minutes", self);
150 (self as u64).minutes()
152 }
153
154 fn hours(self) -> Duration {
155 assert!(self >= 0, "duration cannot be negative: got {} hours", self);
156 (self as u64).hours()
158 }
159
160 fn milliseconds(self) -> Duration {
161 assert!(self >= 0, "duration cannot be negative: got {} milliseconds", self);
162 Duration::from_millis(self as u64)
163 }
164
165 fn microseconds(self) -> Duration {
166 assert!(self >= 0, "duration cannot be negative: got {} microseconds", self);
167 Duration::from_micros(self as u64)
168 }
169
170 fn nanoseconds(self) -> Duration {
171 assert!(self >= 0, "duration cannot be negative: got {} nanoseconds", self);
172 Duration::from_nanos(self as u64)
173 }
174}
175
176#[cfg(test)]
178mod tests {
179 use super::*;
180 use std::time::Duration;
181
182 const MAX_FOR_MINUTES: u64 = u64::MAX / 60;
184 const MAX_FOR_HOURS: u64 = u64::MAX / 3600;
185
186 const OVERFLOW_MINUTES: u64 = MAX_FOR_MINUTES + 1;
187 const OVERFLOW_HOURS: u64 = MAX_FOR_HOURS + 1;
188
189 #[test]
191 fn test_u64_large_units() {
192 let five: u64 = 5;
193 assert_eq!(five.minutes(), Duration::from_secs(5 * 60));
194 assert_eq!(five.hours(), Duration::from_secs(5 * 3600));
195 }
196
197 #[test]
198 #[should_panic(expected = "overflows u64 seconds capacity")]
199 fn test_u64_minutes_panics_on_overflow() {
200 let _ = OVERFLOW_MINUTES.minutes();
201 }
202
203 #[test]
204 #[should_panic(expected = "overflows u64 seconds capacity")]
205 fn test_u64_hours_panics_on_overflow() {
206 let _ = OVERFLOW_HOURS.hours();
207 }
208
209 #[test]
210 fn test_max_u64_small_units() {
211 let max_u64 = u64::MAX;
212 assert_eq!(max_u64.milliseconds(), Duration::from_millis(u64::MAX));
213 assert_eq!(max_u64.microseconds(), Duration::from_micros(u64::MAX));
214 assert_eq!(max_u64.nanoseconds(), Duration::from_nanos(u64::MAX));
215 }
216
217 #[test]
219 fn test_i64_positive() {
220 let pos: i64 = 10;
221 assert_eq!(pos.seconds(), Duration::from_secs(10));
222 assert_eq!(pos.minutes(), Duration::from_secs(600));
223 assert_eq!(pos.hours(), Duration::from_secs(36000));
224 }
225
226 #[test]
227 #[should_panic(expected = "duration cannot be negative")]
228 fn test_i64_negative_panics() {
229 let neg: i64 = -10;
230 let _ = neg.minutes();
231 }
232
233 #[test]
234 #[should_panic(expected = "overflows u64 seconds capacity")]
235 fn test_i64_minutes_panics_on_overflow() {
236 let _ = (OVERFLOW_MINUTES as i64).minutes();
237 }
238
239 #[test]
240 #[should_panic(expected = "overflows u64 seconds capacity")]
241 fn test_i64_hours_panics_on_overflow() {
242 let _ = (OVERFLOW_HOURS as i64).hours();
243 }
244
245 #[test]
248 fn test_i32_positive_full() {
249 let val: i32 = 5;
250 assert_eq!(val.seconds(), Duration::from_secs(5));
251 assert_eq!(val.minutes(), Duration::from_secs(300));
252 assert_eq!(val.hours(), Duration::from_secs(18000));
253 }
254
255 #[test]
256 #[should_panic(expected = "duration cannot be negative")]
257 fn test_i32_negative_panics() { let _ = (-5).seconds(); }
258
259 #[test]
261 fn test_u32_positive_full() {
262 let val: u32 = 5;
263 assert_eq!(val.seconds(), Duration::from_secs(5));
264 assert_eq!(val.minutes(), Duration::from_secs(300));
265 assert_eq!(val.hours(), Duration::from_secs(18000));
266 }
267}