1use crate::helpers::{self, Helpers};
2use crate::Rate;
3use core::cmp::Ordering;
4use core::convert;
5use core::ops;
6
7#[derive(Clone, Copy, Debug)]
12pub struct Duration<T, const NOM: u32, const DENOM: u32> {
13 pub(crate) ticks: T,
14}
15
16macro_rules! shorthand {
17 ($i:ty, $nom:literal, $denum:literal, $unit:ident, $to_unit:ident, $unital:ident, $unitstr:literal) => {
18 #[doc = concat!("Convert the Duration to an integer number of ", $unitstr, ".")]
19 #[inline]
20 pub const fn $to_unit(&self) -> $i {
21 (Helpers::<$nom, $denum, NOM, DENOM>::LD_TIMES_RN as $i * self.ticks)
22 / Helpers::<$nom, $denum, NOM, DENOM>::RD_TIMES_LN as $i
23 }
24
25 #[doc = concat!("Shorthand for creating a duration which represents ", $unitstr, ".")]
26 #[inline]
27 pub const fn $unit(val: $i) -> Self {
28 Self::from_ticks(
29 (Helpers::<$nom, $denum, NOM, DENOM>::RD_TIMES_LN as $i * val)
30 / Helpers::<$nom, $denum, NOM, DENOM>::LD_TIMES_RN as $i
31 )
32 }
33
34 #[doc = concat!("Shorthand for creating a duration which represents ", $unitstr, " (ceil rounded).")]
35 #[inline]
36 pub const fn $unital(val: $i) -> Self {
37 let mul = Helpers::<$nom, $denum, NOM, DENOM>::RD_TIMES_LN as $i * val;
38 let ld_times_rn = Helpers::<$nom, $denum, NOM, DENOM>::LD_TIMES_RN as $i;
39 Self::from_ticks(if mul % ld_times_rn == 0 {
40 mul / ld_times_rn
41 } else {
42 mul / ld_times_rn + 1
43 })
44 }
45 };
46}
47
48macro_rules! impl_duration_for_integer {
49 ($i:ty) => {
50 impl<const NOM: u32, const DENOM: u32> Duration<$i, NOM, DENOM> {
51 #[doc = concat!("let _d = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(1);")]
56 #[inline]
58 pub const fn from_ticks(ticks: $i) -> Self {
59 helpers::greater_than_0::<NOM>();
60 helpers::greater_than_0::<DENOM>();
61
62 Duration { ticks }
63 }
64
65 #[doc = concat!("let d = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(234);")]
70 #[inline]
74 pub const fn ticks(&self) -> $i {
75 self.ticks
76 }
77
78 #[doc = concat!("let zero = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(0);")]
83 #[doc = concat!("let one = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(1);")]
84 #[inline]
89 pub const fn is_zero(&self) -> bool {
90 self.ticks == 0
91 }
92
93 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(1);")]
98 #[doc = concat!("let d2 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(2);")]
99 #[doc = concat!("let d3 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(", stringify!($i), "::MAX);")]
100 pub const fn checked_add<const O_NOM: u32, const O_DENOM: u32>(
105 self,
106 other: Duration<$i, O_NOM, O_DENOM>,
107 ) -> Option<Self> {
108 if Helpers::<NOM, DENOM, O_NOM, O_DENOM>::SAME_BASE {
109 if let Some(ticks) = self.ticks.checked_add(other.ticks) {
110 Some(Duration::<$i, NOM, DENOM>::from_ticks(ticks))
111 } else {
112 None
113 }
114 } else {
115 if let Some(lh) = other
116 .ticks
117 .checked_mul(Helpers::<NOM, DENOM, O_NOM, O_DENOM>::LD_TIMES_RN as $i)
118 {
119 let ticks = lh / Helpers::<NOM, DENOM, O_NOM, O_DENOM>::RD_TIMES_LN as $i;
120
121 if let Some(ticks) = self.ticks.checked_add(ticks) {
122 Some(Duration::<$i, NOM, DENOM>::from_ticks(ticks))
123 } else {
124 None
125 }
126 } else {
127 None
128 }
129 }
130 }
131
132 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(1);")]
137 #[doc = concat!("let d2 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(2);")]
138 #[doc = concat!("let d3 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(", stringify!($i), "::MAX);")]
139 pub const fn checked_sub<const O_NOM: u32, const O_DENOM: u32>(
144 self,
145 other: Duration<$i, O_NOM, O_DENOM>,
146 ) -> Option<Self> {
147 if Helpers::<NOM, DENOM, O_NOM, O_DENOM>::SAME_BASE {
148 if let Some(ticks) = self.ticks.checked_sub(other.ticks) {
149 Some(Duration::<$i, NOM, DENOM>::from_ticks(ticks))
150 } else {
151 None
152 }
153 } else {
154 if let Some(lh) = other
155 .ticks
156 .checked_mul(Helpers::<NOM, DENOM, O_NOM, O_DENOM>::LD_TIMES_RN as $i)
157 {
158 let ticks = lh / Helpers::<NOM, DENOM, O_NOM, O_DENOM>::RD_TIMES_LN as $i;
159
160 if let Some(ticks) = self.ticks.checked_sub(ticks) {
161 Some(Duration::<$i, NOM, DENOM>::from_ticks(ticks))
162 } else {
163 None
164 }
165 } else {
166 None
167 }
168 }
169 }
170
171 #[doc = concat!("Const `cmp` for ", stringify!($i))]
172 #[inline(always)]
173 const fn _const_cmp(a: $i, b: $i) -> Ordering {
174 if a < b {
175 Ordering::Less
176 } else if a > b {
177 Ordering::Greater
178 } else {
179 Ordering::Equal
180 }
181 }
182
183 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_00>::from_ticks(1);")]
188 #[doc = concat!("let d2 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(1);")]
189 #[inline]
193 pub const fn const_partial_cmp<const R_NOM: u32, const R_DENOM: u32>(
194 self,
195 other: Duration<$i, R_NOM, R_DENOM>
196 ) -> Option<Ordering> {
197 if Helpers::<NOM, DENOM, R_NOM, R_DENOM>::SAME_BASE {
213 Some(Self::_const_cmp(self.ticks, other.ticks))
215 } else {
216 let lh = self
217 .ticks
218 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::RD_TIMES_LN as $i);
219 let rh = other
220 .ticks
221 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::LD_TIMES_RN as $i);
222
223 if let (Some(lh), Some(rh)) = (lh, rh) {
224 Some(Self::_const_cmp(lh, rh))
225 } else {
226 None
227 }
228 }
229 }
230
231 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_00>::from_ticks(1);")]
236 #[doc = concat!("let d2 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(10);")]
237 #[inline]
241 pub const fn const_eq<const R_NOM: u32, const R_DENOM: u32>(
242 self,
243 other: Duration<$i, R_NOM, R_DENOM>
244 ) -> bool {
245 if Helpers::<NOM, DENOM, R_NOM, R_DENOM>::SAME_BASE {
246 self.ticks == other.ticks
248 } else {
249 let lh = self
250 .ticks
251 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::RD_TIMES_LN as $i);
252 let rh = other
253 .ticks
254 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::LD_TIMES_RN as $i);
255
256 if let (Some(lh), Some(rh)) = (lh, rh) {
257 lh == rh
258 } else {
259 false
260 }
261 }
262 }
263
264 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_00>::from_ticks(1);")]
269 #[doc = concat!("let d2 = Duration::<", stringify!($i), ", 1, 1_000>::const_try_from(d1);")]
270 pub const fn const_try_from<const I_NOM: u32, const I_DENOM: u32>(
274 duration: Duration<$i, I_NOM, I_DENOM>,
275 ) -> Option<Self> {
276 if Helpers::<I_NOM, I_DENOM, NOM, DENOM>::SAME_BASE {
277 Some(Self::from_ticks(duration.ticks))
278 } else {
279 if let Some(lh) = (duration.ticks as u64)
280 .checked_mul(Helpers::<I_NOM, I_DENOM, NOM, DENOM>::RD_TIMES_LN as u64)
281 {
282 let ticks = lh / Helpers::<I_NOM, I_DENOM, NOM, DENOM>::LD_TIMES_RN as u64;
283
284 if ticks <= <$i>::MAX as u64 {
285 Some(Self::from_ticks(ticks as $i))
286 } else {
287 None
288 }
289 } else {
290 None
291 }
292 }
293 }
294
295 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_00>::from_ticks(1);")]
300 #[doc = concat!("let d2: Option<Duration::<", stringify!($i), ", 1, 1_000>> = d1.const_try_into();")]
301 #[inline]
305 pub const fn const_try_into<const O_NOM: u32, const O_DENOM: u32>(
306 self,
307 ) -> Option<Duration<$i, O_NOM, O_DENOM>> {
308 Duration::<$i, O_NOM, O_DENOM>::const_try_from(self)
309 }
310
311 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(2);")]
316 #[doc = concat!("let r1: Option<Rate::<", stringify!($i), ", 1, 1>> = d1.try_into_rate();")]
317 #[inline]
321 pub const fn try_into_rate<const O_NOM: u32, const O_DENOM: u32>(
322 self,
323 ) -> Option<Rate<$i, O_NOM, O_DENOM>> {
324 Rate::<$i, O_NOM, O_DENOM>::try_from_duration(self)
325 }
326
327 #[inline]
329 pub const fn into_rate<const O_NOM: u32, const O_DENOM: u32>(
330 self,
331 ) -> Rate<$i, O_NOM, O_DENOM> {
332 if let Some(v) = self.try_into_rate() {
333 v
334 } else {
335 panic!("Into rate failed, divide-by-zero!");
336 }
337 }
338
339 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1>::from_raw(1);")]
344 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_000>::try_from_rate(r1);")]
345 #[inline]
349 pub const fn try_from_rate<const I_NOM: u32, const I_DENOM: u32>(
350 rate: Rate<$i, I_NOM, I_DENOM>,
351 ) -> Option<Self> {
352 if rate.raw > 0 {
353 Some(Self::from_ticks(
354 Helpers::<I_NOM, I_DENOM, NOM, DENOM>::RATE_TO_DURATION_NUMERATOR as $i
355 / rate.raw
356 ))
357 } else {
358 None
359 }
360 }
361
362 #[inline]
364 pub const fn from_rate<const I_NOM: u32, const I_DENOM: u32>(
365 rate: Rate<$i, I_NOM, I_DENOM>,
366 ) -> Self {
367 if let Some(v) = Self::try_from_rate(rate) {
368 v
369 } else {
370 panic!("From rate failed, divide-by-zero!");
371 }
372 }
373
374 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 100>::from_ticks(1);")]
381 #[doc = concat!("let d2: Duration::<", stringify!($i), ", 1, 1_000> = d1.convert();")]
382 #[doc = concat!("const TICKS: ", stringify!($i), "= ", stringify!($i), "::MAX - 10;")]
389 #[doc = concat!("const D1: Duration::<", stringify!($i), ", 1, 100> = Duration::<", stringify!($i), ", 1, 100>::from_ticks(TICKS);")]
390 #[doc = concat!("const D2: Duration::<", stringify!($i), ", 1, 200> = D1.convert();")]
392 #[inline]
393 pub const fn convert<const O_NOM: u32, const O_DENOM: u32>(
394 self,
395 ) -> Duration<$i, O_NOM, O_DENOM> {
396 if let Some(v) = self.const_try_into() {
397 v
398 } else {
399 panic!("Convert failed!");
400 }
401 }
402
403 shorthand!($i, 1, 1_000_000_000, nanos, to_nanos, nanos_at_least, "nanoseconds");
404 shorthand!($i, 1, 1_000_000, micros, to_micros, micros_at_least, "microseconds");
405 shorthand!($i, 1, 1_000, millis, to_millis, millis_at_least, "milliseconds");
406 shorthand!($i, 1, 1, secs, to_secs, secs_at_least, "seconds");
407 shorthand!($i, 60, 1, minutes, to_minutes, minutes_at_least, "minutes");
408 shorthand!($i, 3600, 1, hours, to_hours, hours_at_least, "hours");
409
410 #[inline]
412 #[allow(non_snake_case)]
413 pub const fn Hz(val: $i) -> Self {
414 Self::from_rate(crate::Hertz::<$i>::from_raw(val))
415 }
416
417 #[inline]
419 #[allow(non_snake_case)]
420 pub const fn kHz(val: $i) -> Self {
421 Self::from_rate(crate::Kilohertz::<$i>::from_raw(val))
422 }
423
424 #[inline]
426 #[allow(non_snake_case)]
427 pub const fn MHz(val: $i) -> Self {
428 Self::from_rate(crate::Megahertz::<$i>::from_raw(val))
429 }
430 }
431
432 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
433 PartialOrd<Duration<$i, R_NOM, R_DENOM>> for Duration<$i, L_NOM, L_DENOM>
434 {
435 #[inline]
436 fn partial_cmp(&self, other: &Duration<$i, R_NOM, R_DENOM>) -> Option<Ordering> {
437 self.const_partial_cmp(*other)
438 }
439 }
440
441 impl<const NOM: u32, const DENOM: u32> Ord for Duration<$i, NOM, DENOM> {
442 #[inline]
443 fn cmp(&self, other: &Self) -> Ordering {
444 Self::_const_cmp(self.ticks, other.ticks)
445 }
446 }
447
448 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
449 PartialEq<Duration<$i, R_NOM, R_DENOM>> for Duration<$i, L_NOM, L_DENOM>
450 {
451 #[inline]
452 fn eq(&self, other: &Duration<$i, R_NOM, R_DENOM>) -> bool {
453 self.const_eq(*other)
454 }
455 }
456
457 impl<const NOM: u32, const DENOM: u32> Eq for Duration<$i, NOM, DENOM> {}
458
459 impl<const NOM: u32, const DENOM: u32> ops::Sub<Duration<$i, NOM, DENOM>>
462 for Duration<$i, NOM, DENOM>
463 {
464 type Output = Duration<$i, NOM, DENOM>;
465
466 #[inline]
467 fn sub(self, other: Duration<$i, NOM, DENOM>) -> Self::Output {
468 if let Some(v) = self.checked_sub(other) {
469 v
470 } else {
471 panic!("Sub failed!");
472 }
473 }
474 }
475
476 impl<const NOM: u32, const DENOM: u32> ops::SubAssign<Duration<$i, NOM, DENOM>>
478 for Duration<$i, NOM, DENOM>
479 {
480 #[inline]
481 fn sub_assign(&mut self, other: Self) {
482 *self = *self - other;
483 }
484 }
485
486 impl<const NOM: u32, const DENOM: u32> ops::Add<Duration<$i, NOM, DENOM>>
489 for Duration<$i, NOM, DENOM>
490 {
491 type Output = Duration<$i, NOM, DENOM>;
492
493 #[inline]
494 fn add(self, other: Duration<$i, NOM, DENOM>) -> Self::Output {
495 if let Some(v) = self.checked_add(other) {
496 v
497 } else {
498 panic!("Add failed!");
499 }
500 }
501 }
502
503 impl<const NOM: u32, const DENOM: u32> ops::AddAssign<Duration<$i, NOM, DENOM>>
505 for Duration<$i, NOM, DENOM>
506 {
507 #[inline]
508 fn add_assign(&mut self, other: Self) {
509 *self = *self + other;
510 }
511 }
512
513 impl<const NOM: u32, const DENOM: u32> ops::Mul<Duration<$i, NOM, DENOM>> for u32 {
515 type Output = Duration<$i, NOM, DENOM>;
516
517 #[inline]
518 fn mul(self, mut other: Duration<$i, NOM, DENOM>) -> Self::Output {
519 other.ticks *= self as $i;
520 other
521 }
522 }
523
524 impl<const NOM: u32, const DENOM: u32> ops::Mul<u32> for Duration<$i, NOM, DENOM> {
526 type Output = Duration<$i, NOM, DENOM>;
527
528 #[inline]
529 fn mul(mut self, other: u32) -> Self::Output {
530 self.ticks *= other as $i;
531 self
532 }
533 }
534
535 impl<const NOM: u32, const DENOM: u32> ops::MulAssign<u32>
537 for Duration<$i, NOM, DENOM>
538 {
539 #[inline]
540 fn mul_assign(&mut self, other: u32) {
541 *self = *self * other;
542 }
543 }
544
545 impl<const NOM: u32, const DENOM: u32> ops::Div<u32> for Duration<$i, NOM, DENOM> {
547 type Output = Duration<$i, NOM, DENOM>;
548
549 #[inline]
550 fn div(mut self, other: u32) -> Self::Output {
551 self.ticks /= other as $i;
552 self
553 }
554 }
555
556 impl<const NOM: u32, const DENOM: u32> ops::DivAssign<u32>
558 for Duration<$i, NOM, DENOM>
559 {
560 #[inline]
561 fn div_assign(&mut self, other: u32) {
562 *self = *self / other;
563 }
564 }
565
566 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32> ops::Div<Duration<$i, R_NOM, R_DENOM>>
568 for Duration<$i, L_NOM, L_DENOM>
569 {
570 type Output = $i;
571
572 #[inline]
573 fn div(self, other: Duration<$i, R_NOM, R_DENOM>) -> Self::Output {
574 let conv: Duration<$i, R_NOM, R_DENOM> = self.convert();
575 conv.ticks / other.ticks
576 }
577 }
578
579 #[cfg(feature = "defmt")]
580 impl<const NOM: u32, const DENOM: u32> defmt::Format for Duration<$i, NOM, DENOM>
581 {
582 fn format(&self, f: defmt::Formatter) {
583 if NOM == 3_600 && DENOM == 1 {
584 defmt::write!(f, "{} h", self.ticks)
585 } else if NOM == 60 && DENOM == 1 {
586 defmt::write!(f, "{} min", self.ticks)
587 } else if NOM == 1 && DENOM == 1 {
588 defmt::write!(f, "{} s", self.ticks)
589 } else if NOM == 1 && DENOM == 1_000 {
590 defmt::write!(f, "{} ms", self.ticks)
591 } else if NOM == 1 && DENOM == 1_000_000 {
592 defmt::write!(f, "{} us", self.ticks)
593 } else if NOM == 1 && DENOM == 1_000_000_000 {
594 defmt::write!(f, "{} ns", self.ticks)
595 } else {
596 defmt::write!(f, "{} ticks @ ({}/{})", self.ticks, NOM, DENOM)
597 }
598 }
599 }
600
601 impl<const NOM: u32, const DENOM: u32> core::fmt::Display for Duration<$i, NOM, DENOM> {
602 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
603 if NOM == 3_600 && DENOM == 1 {
604 write!(f, "{} h", self.ticks)
605 } else if NOM == 60 && DENOM == 1 {
606 write!(f, "{} min", self.ticks)
607 } else if NOM == 1 && DENOM == 1 {
608 write!(f, "{} s", self.ticks)
609 } else if NOM == 1 && DENOM == 1_000 {
610 write!(f, "{} ms", self.ticks)
611 } else if NOM == 1 && DENOM == 1_000_000 {
612 write!(f, "{} us", self.ticks)
613 } else if NOM == 1 && DENOM == 1_000_000_000 {
614 write!(f, "{} ns", self.ticks)
615 } else {
616 write!(f, "{} ticks @ ({}/{})", self.ticks, NOM, DENOM)
617 }
618 }
619 }
620 };
621}
622
623impl_duration_for_integer!(u32);
624impl_duration_for_integer!(u64);
625
626impl<const NOM: u32, const DENOM: u32> From<Duration<u32, NOM, DENOM>>
631 for Duration<u64, NOM, DENOM>
632{
633 #[inline]
634 fn from(val: Duration<u32, NOM, DENOM>) -> Duration<u64, NOM, DENOM> {
635 Duration::<u64, NOM, DENOM>::from_ticks(val.ticks() as u64)
636 }
637}
638
639impl<const NOM: u32, const DENOM: u32> convert::TryFrom<Duration<u64, NOM, DENOM>>
640 for Duration<u32, NOM, DENOM>
641{
642 type Error = ();
643
644 #[inline]
645 fn try_from(val: Duration<u64, NOM, DENOM>) -> Result<Duration<u32, NOM, DENOM>, ()> {
646 Ok(Duration::<u32, NOM, DENOM>::from_ticks(
647 val.ticks().try_into().map_err(|_| ())?,
648 ))
649 }
650}
651
652impl<const NOM: u32, const DENOM: u32> ops::Sub<Duration<u32, NOM, DENOM>>
655 for Duration<u64, NOM, DENOM>
656{
657 type Output = Duration<u64, NOM, DENOM>;
658
659 #[inline]
660 fn sub(self, other: Duration<u32, NOM, DENOM>) -> Self::Output {
661 if let Some(v) =
662 self.checked_sub(Duration::<u64, NOM, DENOM>::from_ticks(other.ticks() as u64))
663 {
664 v
665 } else {
666 panic!("Sub failed!");
667 }
668 }
669}
670
671impl<const NOM: u32, const DENOM: u32> ops::SubAssign<Duration<u32, NOM, DENOM>>
673 for Duration<u64, NOM, DENOM>
674{
675 #[inline]
676 fn sub_assign(&mut self, other: Duration<u32, NOM, DENOM>) {
677 *self = *self - other;
678 }
679}
680
681impl<const NOM: u32, const DENOM: u32> ops::Add<Duration<u32, NOM, DENOM>>
684 for Duration<u64, NOM, DENOM>
685{
686 type Output = Duration<u64, NOM, DENOM>;
687
688 #[inline]
689 fn add(self, other: Duration<u32, NOM, DENOM>) -> Self::Output {
690 if let Some(v) =
691 self.checked_add(Duration::<u64, NOM, DENOM>::from_ticks(other.ticks() as u64))
692 {
693 v
694 } else {
695 panic!("Add failed!");
696 }
697 }
698}
699
700impl<const NOM: u32, const DENOM: u32> ops::AddAssign<Duration<u32, NOM, DENOM>>
702 for Duration<u64, NOM, DENOM>
703{
704 #[inline]
705 fn add_assign(&mut self, other: Duration<u32, NOM, DENOM>) {
706 *self = *self + other;
707 }
708}
709
710impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
711 PartialOrd<Duration<u32, R_NOM, R_DENOM>> for Duration<u64, L_NOM, L_DENOM>
712{
713 #[inline]
714 fn partial_cmp(&self, other: &Duration<u32, R_NOM, R_DENOM>) -> Option<Ordering> {
715 self.partial_cmp(&Duration::<u64, R_NOM, R_DENOM>::from_ticks(
716 other.ticks() as u64
717 ))
718 }
719}
720
721impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
722 PartialEq<Duration<u32, R_NOM, R_DENOM>> for Duration<u64, L_NOM, L_DENOM>
723{
724 #[inline]
725 fn eq(&self, other: &Duration<u32, R_NOM, R_DENOM>) -> bool {
726 self.eq(&Duration::<u64, R_NOM, R_DENOM>::from_ticks(
727 other.ticks() as u64
728 ))
729 }
730}
731
732impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
733 PartialOrd<Duration<u64, R_NOM, R_DENOM>> for Duration<u32, L_NOM, L_DENOM>
734{
735 #[inline]
736 fn partial_cmp(&self, other: &Duration<u64, R_NOM, R_DENOM>) -> Option<Ordering> {
737 Duration::<u64, L_NOM, L_DENOM>::from_ticks(self.ticks as u64).partial_cmp(other)
738 }
739}
740
741impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
742 PartialEq<Duration<u64, R_NOM, R_DENOM>> for Duration<u32, L_NOM, L_DENOM>
743{
744 #[inline]
745 fn eq(&self, other: &Duration<u64, R_NOM, R_DENOM>) -> bool {
746 Duration::<u64, L_NOM, L_DENOM>::from_ticks(self.ticks as u64).eq(other)
747 }
748}
749
750pub trait ExtU32 {
752 fn nanos<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
754
755 fn micros<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
757
758 fn millis<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
760
761 fn secs<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
763
764 fn minutes<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
766
767 fn hours<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
769}
770
771impl ExtU32 for u32 {
772 #[inline]
773 fn nanos<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
774 Duration::<u32, NOM, DENOM>::nanos(self)
775 }
776
777 #[inline]
778 fn micros<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
779 Duration::<u32, NOM, DENOM>::micros(self)
780 }
781
782 #[inline]
783 fn millis<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
784 Duration::<u32, NOM, DENOM>::millis(self)
785 }
786
787 #[inline]
788 fn secs<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
789 Duration::<u32, NOM, DENOM>::secs(self)
790 }
791
792 #[inline]
793 fn minutes<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
794 Duration::<u32, NOM, DENOM>::minutes(self)
795 }
796
797 #[inline]
798 fn hours<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
799 Duration::<u32, NOM, DENOM>::hours(self)
800 }
801}
802
803pub trait ExtU32Ceil {
805 fn nanos_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
807
808 fn micros_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
810
811 fn millis_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
813
814 fn secs_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
816
817 fn minutes_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
819
820 fn hours_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM>;
822}
823
824impl ExtU32Ceil for u32 {
825 #[inline]
826 fn nanos_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
827 Duration::<u32, NOM, DENOM>::nanos_at_least(self)
828 }
829
830 #[inline]
831 fn micros_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
832 Duration::<u32, NOM, DENOM>::micros_at_least(self)
833 }
834
835 #[inline]
836 fn millis_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
837 Duration::<u32, NOM, DENOM>::millis_at_least(self)
838 }
839
840 #[inline]
841 fn secs_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
842 Duration::<u32, NOM, DENOM>::secs_at_least(self)
843 }
844
845 #[inline]
846 fn minutes_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
847 Duration::<u32, NOM, DENOM>::minutes_at_least(self)
848 }
849
850 #[inline]
851 fn hours_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u32, NOM, DENOM> {
852 Duration::<u32, NOM, DENOM>::hours_at_least(self)
853 }
854}
855
856pub trait ExtU64 {
858 fn nanos<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
860
861 fn micros<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
863
864 fn millis<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
866
867 fn secs<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
869
870 fn minutes<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
872
873 fn hours<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
875}
876
877impl ExtU64 for u64 {
878 #[inline]
879 fn nanos<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
880 Duration::<u64, NOM, DENOM>::nanos(self)
881 }
882
883 #[inline]
884 fn micros<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
885 Duration::<u64, NOM, DENOM>::micros(self)
886 }
887
888 #[inline]
889 fn millis<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
890 Duration::<u64, NOM, DENOM>::millis(self)
891 }
892
893 #[inline]
894 fn secs<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
895 Duration::<u64, NOM, DENOM>::secs(self)
896 }
897
898 #[inline]
899 fn minutes<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
900 Duration::<u64, NOM, DENOM>::minutes(self)
901 }
902
903 #[inline]
904 fn hours<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
905 Duration::<u64, NOM, DENOM>::hours(self)
906 }
907}
908
909pub trait ExtU64Ceil {
911 fn nanos_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
913
914 fn micros_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
916
917 fn millis_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
919
920 fn secs_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
922
923 fn minutes_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
925
926 fn hours_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM>;
928}
929
930impl ExtU64Ceil for u64 {
931 #[inline]
932 fn nanos_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
933 Duration::<u64, NOM, DENOM>::nanos_at_least(self)
934 }
935
936 #[inline]
937 fn micros_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
938 Duration::<u64, NOM, DENOM>::micros_at_least(self)
939 }
940
941 #[inline]
942 fn millis_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
943 Duration::<u64, NOM, DENOM>::millis_at_least(self)
944 }
945
946 #[inline]
947 fn secs_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
948 Duration::<u64, NOM, DENOM>::secs_at_least(self)
949 }
950
951 #[inline]
952 fn minutes_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
953 Duration::<u64, NOM, DENOM>::minutes_at_least(self)
954 }
955
956 #[inline]
957 fn hours_at_least<const NOM: u32, const DENOM: u32>(self) -> Duration<u64, NOM, DENOM> {
958 Duration::<u64, NOM, DENOM>::hours_at_least(self)
959 }
960}