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