1 | //! Extension traits. |
2 | |
3 | use core::time::Duration as StdDuration; |
4 | |
5 | use crate::convert::*; |
6 | use crate::Duration; |
7 | |
8 | /// Sealed trait to prevent downstream implementations. |
9 | mod sealed { |
10 | /// A trait that cannot be implemented by downstream users. |
11 | pub trait Sealed {} |
12 | impl Sealed for i64 {} |
13 | impl Sealed for u64 {} |
14 | impl Sealed for f64 {} |
15 | } |
16 | |
17 | // region: NumericalDuration |
18 | /// Create [`Duration`]s from numeric literals. |
19 | /// |
20 | /// # Examples |
21 | /// |
22 | /// Basic construction of [`Duration`]s. |
23 | /// |
24 | /// ```rust |
25 | /// # use time::{Duration, ext::NumericalDuration}; |
26 | /// assert_eq!(5.nanoseconds(), Duration::nanoseconds(5)); |
27 | /// assert_eq!(5.microseconds(), Duration::microseconds(5)); |
28 | /// assert_eq!(5.milliseconds(), Duration::milliseconds(5)); |
29 | /// assert_eq!(5.seconds(), Duration::seconds(5)); |
30 | /// assert_eq!(5.minutes(), Duration::minutes(5)); |
31 | /// assert_eq!(5.hours(), Duration::hours(5)); |
32 | /// assert_eq!(5.days(), Duration::days(5)); |
33 | /// assert_eq!(5.weeks(), Duration::weeks(5)); |
34 | /// ``` |
35 | /// |
36 | /// Signed integers work as well! |
37 | /// |
38 | /// ```rust |
39 | /// # use time::{Duration, ext::NumericalDuration}; |
40 | /// assert_eq!((-5).nanoseconds(), Duration::nanoseconds(-5)); |
41 | /// assert_eq!((-5).microseconds(), Duration::microseconds(-5)); |
42 | /// assert_eq!((-5).milliseconds(), Duration::milliseconds(-5)); |
43 | /// assert_eq!((-5).seconds(), Duration::seconds(-5)); |
44 | /// assert_eq!((-5).minutes(), Duration::minutes(-5)); |
45 | /// assert_eq!((-5).hours(), Duration::hours(-5)); |
46 | /// assert_eq!((-5).days(), Duration::days(-5)); |
47 | /// assert_eq!((-5).weeks(), Duration::weeks(-5)); |
48 | /// ``` |
49 | /// |
50 | /// Just like any other [`Duration`], they can be added, subtracted, etc. |
51 | /// |
52 | /// ```rust |
53 | /// # use time::ext::NumericalDuration; |
54 | /// assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds()); |
55 | /// assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds()); |
56 | /// ``` |
57 | /// |
58 | /// When called on floating point values, any remainder of the floating point value will be |
59 | /// truncated. Keep in mind that floating point numbers are inherently imprecise and have limited |
60 | /// capacity. |
61 | pub trait NumericalDuration: sealed::Sealed { |
62 | /// Create a [`Duration`] from the number of nanoseconds. |
63 | fn nanoseconds(self) -> Duration; |
64 | /// Create a [`Duration`] from the number of microseconds. |
65 | fn microseconds(self) -> Duration; |
66 | /// Create a [`Duration`] from the number of milliseconds. |
67 | fn milliseconds(self) -> Duration; |
68 | /// Create a [`Duration`] from the number of seconds. |
69 | fn seconds(self) -> Duration; |
70 | /// Create a [`Duration`] from the number of minutes. |
71 | fn minutes(self) -> Duration; |
72 | /// Create a [`Duration`] from the number of hours. |
73 | fn hours(self) -> Duration; |
74 | /// Create a [`Duration`] from the number of days. |
75 | fn days(self) -> Duration; |
76 | /// Create a [`Duration`] from the number of weeks. |
77 | fn weeks(self) -> Duration; |
78 | } |
79 | |
80 | impl NumericalDuration for i64 { |
81 | fn nanoseconds(self) -> Duration { |
82 | Duration::nanoseconds(self) |
83 | } |
84 | |
85 | fn microseconds(self) -> Duration { |
86 | Duration::microseconds(self) |
87 | } |
88 | |
89 | fn milliseconds(self) -> Duration { |
90 | Duration::milliseconds(self) |
91 | } |
92 | |
93 | fn seconds(self) -> Duration { |
94 | Duration::seconds(self) |
95 | } |
96 | |
97 | fn minutes(self) -> Duration { |
98 | Duration::minutes(self) |
99 | } |
100 | |
101 | fn hours(self) -> Duration { |
102 | Duration::hours(self) |
103 | } |
104 | |
105 | fn days(self) -> Duration { |
106 | Duration::days(self) |
107 | } |
108 | |
109 | fn weeks(self) -> Duration { |
110 | Duration::weeks(self) |
111 | } |
112 | } |
113 | |
114 | impl NumericalDuration for f64 { |
115 | fn nanoseconds(self) -> Duration { |
116 | Duration::nanoseconds(self as _) |
117 | } |
118 | |
119 | fn microseconds(self) -> Duration { |
120 | Duration::nanoseconds((self * Nanosecond.per(Microsecond) as Self) as _) |
121 | } |
122 | |
123 | fn milliseconds(self) -> Duration { |
124 | Duration::nanoseconds((self * Nanosecond.per(Millisecond) as Self) as _) |
125 | } |
126 | |
127 | fn seconds(self) -> Duration { |
128 | Duration::nanoseconds((self * Nanosecond.per(Second) as Self) as _) |
129 | } |
130 | |
131 | fn minutes(self) -> Duration { |
132 | Duration::nanoseconds((self * Nanosecond.per(Minute) as Self) as _) |
133 | } |
134 | |
135 | fn hours(self) -> Duration { |
136 | Duration::nanoseconds((self * Nanosecond.per(Hour) as Self) as _) |
137 | } |
138 | |
139 | fn days(self) -> Duration { |
140 | Duration::nanoseconds((self * Nanosecond.per(Day) as Self) as _) |
141 | } |
142 | |
143 | fn weeks(self) -> Duration { |
144 | Duration::nanoseconds((self * Nanosecond.per(Week) as Self) as _) |
145 | } |
146 | } |
147 | // endregion NumericalDuration |
148 | |
149 | // region: NumericalStdDuration |
150 | /// Create [`std::time::Duration`]s from numeric literals. |
151 | /// |
152 | /// # Examples |
153 | /// |
154 | /// Basic construction of [`std::time::Duration`]s. |
155 | /// |
156 | /// ```rust |
157 | /// # use time::ext::NumericalStdDuration; |
158 | /// # use core::time::Duration; |
159 | /// assert_eq!(5.std_nanoseconds(), Duration::from_nanos(5)); |
160 | /// assert_eq!(5.std_microseconds(), Duration::from_micros(5)); |
161 | /// assert_eq!(5.std_milliseconds(), Duration::from_millis(5)); |
162 | /// assert_eq!(5.std_seconds(), Duration::from_secs(5)); |
163 | /// assert_eq!(5.std_minutes(), Duration::from_secs(5 * 60)); |
164 | /// assert_eq!(5.std_hours(), Duration::from_secs(5 * 3_600)); |
165 | /// assert_eq!(5.std_days(), Duration::from_secs(5 * 86_400)); |
166 | /// assert_eq!(5.std_weeks(), Duration::from_secs(5 * 604_800)); |
167 | /// ``` |
168 | /// |
169 | /// Just like any other [`std::time::Duration`], they can be added, subtracted, etc. |
170 | /// |
171 | /// ```rust |
172 | /// # use time::ext::NumericalStdDuration; |
173 | /// assert_eq!( |
174 | /// 2.std_seconds() + 500.std_milliseconds(), |
175 | /// 2_500.std_milliseconds() |
176 | /// ); |
177 | /// assert_eq!( |
178 | /// 2.std_seconds() - 500.std_milliseconds(), |
179 | /// 1_500.std_milliseconds() |
180 | /// ); |
181 | /// ``` |
182 | /// |
183 | /// When called on floating point values, any remainder of the floating point value will be |
184 | /// truncated. Keep in mind that floating point numbers are inherently imprecise and have limited |
185 | /// capacity. |
186 | pub trait NumericalStdDuration: sealed::Sealed { |
187 | /// Create a [`std::time::Duration`] from the number of nanoseconds. |
188 | fn std_nanoseconds(self) -> StdDuration; |
189 | /// Create a [`std::time::Duration`] from the number of microseconds. |
190 | fn std_microseconds(self) -> StdDuration; |
191 | /// Create a [`std::time::Duration`] from the number of milliseconds. |
192 | fn std_milliseconds(self) -> StdDuration; |
193 | /// Create a [`std::time::Duration`] from the number of seconds. |
194 | fn std_seconds(self) -> StdDuration; |
195 | /// Create a [`std::time::Duration`] from the number of minutes. |
196 | fn std_minutes(self) -> StdDuration; |
197 | /// Create a [`std::time::Duration`] from the number of hours. |
198 | fn std_hours(self) -> StdDuration; |
199 | /// Create a [`std::time::Duration`] from the number of days. |
200 | fn std_days(self) -> StdDuration; |
201 | /// Create a [`std::time::Duration`] from the number of weeks. |
202 | fn std_weeks(self) -> StdDuration; |
203 | } |
204 | |
205 | impl NumericalStdDuration for u64 { |
206 | fn std_nanoseconds(self) -> StdDuration { |
207 | StdDuration::from_nanos(self) |
208 | } |
209 | |
210 | fn std_microseconds(self) -> StdDuration { |
211 | StdDuration::from_micros(self) |
212 | } |
213 | |
214 | fn std_milliseconds(self) -> StdDuration { |
215 | StdDuration::from_millis(self) |
216 | } |
217 | |
218 | fn std_seconds(self) -> StdDuration { |
219 | StdDuration::from_secs(self) |
220 | } |
221 | |
222 | fn std_minutes(self) -> StdDuration { |
223 | StdDuration::from_secs(self * Second.per(Minute) as Self) |
224 | } |
225 | |
226 | fn std_hours(self) -> StdDuration { |
227 | StdDuration::from_secs(self * Second.per(Hour) as Self) |
228 | } |
229 | |
230 | fn std_days(self) -> StdDuration { |
231 | StdDuration::from_secs(self * Second.per(Day) as Self) |
232 | } |
233 | |
234 | fn std_weeks(self) -> StdDuration { |
235 | StdDuration::from_secs(self * Second.per(Week) as Self) |
236 | } |
237 | } |
238 | |
239 | impl NumericalStdDuration for f64 { |
240 | fn std_nanoseconds(self) -> StdDuration { |
241 | assert!(self >= 0.); |
242 | StdDuration::from_nanos(self as _) |
243 | } |
244 | |
245 | fn std_microseconds(self) -> StdDuration { |
246 | assert!(self >= 0.); |
247 | StdDuration::from_nanos((self * Nanosecond.per(Microsecond) as Self) as _) |
248 | } |
249 | |
250 | fn std_milliseconds(self) -> StdDuration { |
251 | assert!(self >= 0.); |
252 | StdDuration::from_nanos((self * Nanosecond.per(Millisecond) as Self) as _) |
253 | } |
254 | |
255 | fn std_seconds(self) -> StdDuration { |
256 | assert!(self >= 0.); |
257 | StdDuration::from_nanos((self * Nanosecond.per(Second) as Self) as _) |
258 | } |
259 | |
260 | fn std_minutes(self) -> StdDuration { |
261 | assert!(self >= 0.); |
262 | StdDuration::from_nanos((self * Nanosecond.per(Minute) as Self) as _) |
263 | } |
264 | |
265 | fn std_hours(self) -> StdDuration { |
266 | assert!(self >= 0.); |
267 | StdDuration::from_nanos((self * Nanosecond.per(Hour) as Self) as _) |
268 | } |
269 | |
270 | fn std_days(self) -> StdDuration { |
271 | assert!(self >= 0.); |
272 | StdDuration::from_nanos((self * Nanosecond.per(Day) as Self) as _) |
273 | } |
274 | |
275 | fn std_weeks(self) -> StdDuration { |
276 | assert!(self >= 0.); |
277 | StdDuration::from_nanos((self * Nanosecond.per(Week) as Self) as _) |
278 | } |
279 | } |
280 | // endregion NumericalStdDuration |
281 | |