1use std::time::Duration;
2
3pub trait DurationExt {
8 fn seconds(self) -> Duration;
10 fn minutes(self) -> Duration;
12 fn hours(self) -> Duration;
14 fn days(self) -> Duration;
16 fn weeks(self) -> Duration;
18 fn milliseconds(self) -> Duration;
20 fn microseconds(self) -> Duration;
22 fn nanoseconds(self) -> Duration;
24}
25
26impl DurationExt for u64 {
27 fn seconds(self) -> Duration {
28 Duration::from_secs(self)
29 }
30
31 fn minutes(self) -> Duration {
32 Duration::from_secs(self.saturating_mul(60))
33 }
34
35 fn hours(self) -> Duration {
36 Duration::from_secs(self.saturating_mul(3600))
37 }
38
39 fn days(self) -> Duration {
40 Duration::from_secs(self.saturating_mul(86400))
41 }
42
43 fn weeks(self) -> Duration {
44 Duration::from_secs(self.saturating_mul(604800))
45 }
46
47 fn milliseconds(self) -> Duration {
48 Duration::from_millis(self)
49 }
50
51 fn microseconds(self) -> Duration {
52 Duration::from_micros(self)
53 }
54
55 fn nanoseconds(self) -> Duration {
56 Duration::from_nanos(self)
57 }
58}
59
60impl DurationExt for u32 {
61 fn seconds(self) -> Duration {
62 Duration::from_secs(self as u64)
63 }
64
65 fn minutes(self) -> Duration {
66 Duration::from_secs((self as u64).saturating_mul(60))
67 }
68
69 fn hours(self) -> Duration {
70 Duration::from_secs((self as u64).saturating_mul(3600))
71 }
72
73 fn days(self) -> Duration {
74 Duration::from_secs((self as u64).saturating_mul(86400))
75 }
76
77 fn weeks(self) -> Duration {
78 Duration::from_secs((self as u64).saturating_mul(604800))
79 }
80
81 fn milliseconds(self) -> Duration {
82 Duration::from_millis(self as u64)
83 }
84
85 fn microseconds(self) -> Duration {
86 Duration::from_micros(self as u64)
87 }
88
89 fn nanoseconds(self) -> Duration {
90 Duration::from_nanos(self as u64)
91 }
92}
93
94impl DurationExt for i64 {
95 fn seconds(self) -> Duration {
96 assert!(self >= 0, "duration cannot be negative: got {} seconds", self);
97 Duration::from_secs(self as u64)
98 }
99
100 fn minutes(self) -> Duration {
101 assert!(self >= 0, "duration cannot be negative: got {} minutes", self);
102
103 Duration::from_secs((self as u64).saturating_mul(60))
104 }
105
106 fn hours(self) -> Duration {
107 assert!(self >= 0, "duration cannot be negative: got {} hours", self);
108
109 Duration::from_secs((self as u64).saturating_mul(3600))
110 }
111
112 fn days(self) -> Duration {
113 assert!(self >= 0, "duration cannot be negative: got {} days", self);
114
115 Duration::from_secs((self as u64).saturating_mul(86400))
116 }
117
118 fn weeks(self) -> Duration {
119 assert!(self >= 0, "duration cannot be negative: got {} weeks", self);
120
121 Duration::from_secs((self as u64).saturating_mul(604800))
122 }
123
124 fn milliseconds(self) -> Duration {
125 assert!(self >= 0, "duration cannot be negative: got {} milliseconds", self);
126
127 Duration::from_millis(self as u64)
128 }
129
130 fn microseconds(self) -> Duration {
131 assert!(self >= 0, "duration cannot be negative: got {} microseconds", self);
132
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 Duration::from_secs((self as u64).saturating_mul(60))
151 }
152
153 fn hours(self) -> Duration {
154 assert!(self >= 0, "duration cannot be negative: got {} hours", self);
155 Duration::from_secs((self as u64).saturating_mul(3600))
156 }
157
158 fn days(self) -> Duration {
159 assert!(self >= 0, "duration cannot be negative: got {} days", self);
160 Duration::from_secs((self as u64).saturating_mul(86400))
161 }
162
163 fn weeks(self) -> Duration {
164 assert!(self >= 0, "duration cannot be negative: got {} weeks", self);
165 Duration::from_secs((self as u64).saturating_mul(604800))
166 }
167
168 fn milliseconds(self) -> Duration {
169 assert!(self >= 0, "duration cannot be negative: got {} milliseconds", self);
170 Duration::from_millis(self as u64)
171 }
172
173 fn microseconds(self) -> Duration {
174 assert!(self >= 0, "duration cannot be negative: got {} microseconds", self);
175 Duration::from_micros(self as u64)
176 }
177
178 fn nanoseconds(self) -> Duration {
179 assert!(self >= 0, "duration cannot be negative: got {} nanoseconds", self);
180 Duration::from_nanos(self as u64)
181 }
182}
183
184#[cfg(test)]
185mod tests {
186 use super::*;
187 use std::time::Duration;
188
189 #[test]
191 fn test_u64_large_units() {
192 let five: u64 = 5;
193 assert_eq!(five.seconds(), Duration::from_secs(5));
194 assert_eq!(five.minutes(), Duration::from_secs(5 * 60));
195 assert_eq!(five.hours(), Duration::from_secs(5 * 3600));
196 assert_eq!(five.days(), Duration::from_secs(5 * 86400));
197 assert_eq!(five.weeks(), Duration::from_secs(5 * 604800));
198 }
199
200 #[test]
201 fn test_u64_small_units() {
202 let one: u64 = 1;
203 assert_eq!(one.milliseconds(), Duration::from_millis(1));
204 assert_eq!(one.microseconds(), Duration::from_micros(1));
205 assert_eq!(one.nanoseconds(), Duration::from_nanos(1));
206
207 let large_num: u64 = 1_234_567;
208 assert_eq!(large_num.milliseconds(), Duration::from_millis(1_234_567));
209 }
210
211 #[test]
213 fn test_u32_large_units() {
214 let three: u32 = 3;
215 assert_eq!(three.seconds(), Duration::from_secs(3));
216 assert_eq!(three.minutes(), Duration::from_secs(3 * 60));
217 assert_eq!(three.hours(), Duration::from_secs(3 * 3600));
218 }
219
220 #[test]
221 fn test_u32_small_units() {
222 let num: u32 = 999;
223 assert_eq!(num.milliseconds(), Duration::from_millis(999));
224 assert_eq!(num.microseconds(), Duration::from_micros(999));
225 assert_eq!(num.nanoseconds(), Duration::from_nanos(999));
226 }
227
228 #[test]
230fn test_i64_positive() {
231 let pos_ten: i64 = 10;
232 assert_eq!(pos_ten.minutes(), Duration::from_secs(600));
233 assert_eq!(pos_ten.milliseconds(), Duration::from_millis(10));
234}
235
236#[test]
237#[should_panic(expected = "duration cannot be negative")]
238fn test_i64_negative_panics() {
239 let neg_ten: i64 = -10;
240 let _ = neg_ten.minutes();
241}
242
243#[test]
244fn test_i64_zero() {
245 let zero: i64 = 0;
246 assert_eq!(zero.seconds(), Duration::ZERO);
247}
248
249#[test]
251fn test_i32_positive() {
252 let pos_two: i32 = 2;
253 assert_eq!(pos_two.days(), Duration::from_secs(2 * 86400));
254 assert_eq!(pos_two.microseconds(), Duration::from_micros(2));
255}
256
257#[test]
258#[should_panic(expected = "duration cannot be negative")]
259fn test_i32_negative_panics() {
260 let neg_two: i32 = -2;
261 let _ = neg_two.days();
262}
263
264#[test]
265fn test_i32_zero() {
266 let zero: i32 = 0;
267 assert_eq!(zero.seconds(), Duration::ZERO);
268}
269 #[test]
271 fn test_saturating_mul_no_panic() {
272 let max_u64 = u64::MAX;
273 let duration = max_u64.minutes();
275 assert!(duration.as_secs() > 0);
276
277 let small_duration = max_u64.milliseconds();
281 assert!(small_duration.as_millis() > 0);
282 }
283}