1use crate::helpers::{self, Helpers};
2use crate::Duration;
3use core::cmp::Ordering;
4use core::convert;
5use core::ops;
6
7#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
12#[cfg_attr(
13 feature = "postcard_max_size",
14 derive(postcard::experimental::max_size::MaxSize)
15)]
16#[derive(Clone, Copy, Debug)]
17pub struct Rate<T, const NOM: u32, const DENOM: u32> {
18 pub(crate) raw: T,
19}
20
21macro_rules! impl_rate_for_integer {
22 ($i:ty) => {
23 impl<const NOM: u32, const DENOM: u32> Rate<$i, NOM, DENOM> {
24 #[doc = concat!("let _d = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(1);")]
29 #[inline]
31 pub const fn from_raw(raw: $i) -> Self {
32 helpers::greater_than_0::<NOM>();
33 helpers::greater_than_0::<DENOM>();
34
35 Rate { raw }
36 }
37
38 #[doc = concat!("let d = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(234);")]
43 #[inline]
47 pub const fn raw(&self) -> $i {
48 self.raw
49 }
50
51 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(1);")]
56 #[doc = concat!("let r2 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(2);")]
57 #[doc = concat!("let r3 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(", stringify!($i), "::MAX);")]
58 pub const fn checked_add<const O_NOM: u32, const O_DENOM: u32>(
63 self,
64 other: Rate<$i, O_NOM, O_DENOM>,
65 ) -> Option<Self> {
66 if Helpers::<NOM, DENOM, O_NOM, O_DENOM>::SAME_BASE {
67 if let Some(raw) = self.raw.checked_add(other.raw) {
68 Some(Rate::<$i, NOM, DENOM>::from_raw(raw))
69 } else {
70 None
71 }
72 } else {
73 if let Some(lh) = other
74 .raw
75 .checked_mul(Helpers::<NOM, DENOM, O_NOM, O_DENOM>::LD_TIMES_RN as $i)
76 {
77 let raw = lh / Helpers::<NOM, DENOM, O_NOM, O_DENOM>::RD_TIMES_LN as $i;
78
79 if let Some(raw) = self.raw.checked_add(raw) {
80 Some(Rate::<$i, NOM, DENOM>::from_raw(raw))
81 } else {
82 None
83 }
84 } else {
85 None
86 }
87 }
88 }
89
90 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(1);")]
95 #[doc = concat!("let r2 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(2);")]
96 #[doc = concat!("let r3 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(", stringify!($i), "::MAX);")]
97 pub const fn checked_sub<const O_NOM: u32, const O_DENOM: u32>(
102 self,
103 other: Rate<$i, O_NOM, O_DENOM>,
104 ) -> Option<Self> {
105 if Helpers::<NOM, DENOM, O_NOM, O_DENOM>::SAME_BASE {
106 if let Some(raw) = self.raw.checked_sub(other.raw) {
107 Some(Rate::<$i, NOM, DENOM>::from_raw(raw))
108 } else {
109 None
110 }
111 } else {
112 if let Some(lh) = other
113 .raw
114 .checked_mul(Helpers::<NOM, DENOM, O_NOM, O_DENOM>::LD_TIMES_RN as $i)
115 {
116 let raw = lh / Helpers::<NOM, DENOM, O_NOM, O_DENOM>::RD_TIMES_LN as $i;
117
118 if let Some(raw) = self.raw.checked_sub(raw) {
119 Some(Rate::<$i, NOM, DENOM>::from_raw(raw))
120 } else {
121 None
122 }
123 } else {
124 None
125 }
126 }
127 }
128
129 #[doc = concat!("Const `cmp` for ", stringify!($i))]
130 #[inline(always)]
131 const fn _const_cmp(a: $i, b: $i) -> Ordering {
132 if a < b {
133 Ordering::Less
134 } else if a > b {
135 Ordering::Greater
136 } else {
137 Ordering::Equal
138 }
139 }
140
141 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_00>::from_raw(1);")]
146 #[doc = concat!("let r2 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(1);")]
147 #[inline]
151 pub const fn const_partial_cmp<const R_NOM: u32, const R_DENOM: u32>(
152 self,
153 other: Rate<$i, R_NOM, R_DENOM>
154 ) -> Option<Ordering> {
155 if Helpers::<NOM, DENOM, R_NOM, R_DENOM>::SAME_BASE {
156 Some(Self::_const_cmp(self.raw, other.raw))
158 } else {
159 let lh = self
160 .raw
161 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::RD_TIMES_LN as $i);
162 let rh = other
163 .raw
164 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::LD_TIMES_RN as $i);
165
166 if let (Some(lh), Some(rh)) = (lh, rh) {
167 Some(Self::_const_cmp(lh, rh))
168 } else {
169 None
170 }
171 }
172 }
173
174 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_00>::from_raw(1);")]
179 #[doc = concat!("let r2 = Rate::<", stringify!($i), ", 1, 1_000>::from_raw(10);")]
180 #[inline]
184 pub const fn const_eq<const R_NOM: u32, const R_DENOM: u32>(
185 self,
186 other: Rate<$i, R_NOM, R_DENOM>
187 ) -> bool {
188 if Helpers::<NOM, DENOM, R_NOM, R_DENOM>::SAME_BASE {
189 self.raw == other.raw
191 } else {
192 let lh = self
193 .raw
194 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::RD_TIMES_LN as $i);
195 let rh = other
196 .raw
197 .checked_mul(Helpers::<NOM, DENOM, R_NOM, R_DENOM>::LD_TIMES_RN as $i);
198
199 if let (Some(lh), Some(rh)) = (lh, rh) {
200 lh == rh
201 } else {
202 false
203 }
204 }
205 }
206
207 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_00>::from_raw(1);")]
212 #[doc = concat!("let r2 = Rate::<", stringify!($i), ", 1, 1_000>::const_try_from(r1);")]
213 pub const fn const_try_from<const I_NOM: u32, const I_DENOM: u32>(
217 rate: Rate<$i, I_NOM, I_DENOM>,
218 ) -> Option<Self> {
219 if Helpers::<I_NOM, I_DENOM, NOM, DENOM>::SAME_BASE {
220 Some(Self::from_raw(rate.raw))
221 } else {
222 if let Some(lh) = (rate.raw as u64)
223 .checked_mul(Helpers::<I_NOM, I_DENOM, NOM, DENOM>::RD_TIMES_LN)
224 {
225 let raw = lh / Helpers::<I_NOM, I_DENOM, NOM, DENOM>::LD_TIMES_RN;
226
227 if raw <= <$i>::MAX as u64 {
228 Some(Self::from_raw(raw as $i))
229 } else {
230 None
231 }
232 } else {
233 None
234 }
235 }
236 }
237
238 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1_00>::from_raw(1);")]
243 #[doc = concat!("let r2: Option<Rate::<", stringify!($i), ", 1, 1_000>> = r1.const_try_into();")]
244 #[inline]
248 pub const fn const_try_into<const O_NOM: u32, const O_DENOM: u32>(
249 self,
250 ) -> Option<Rate<$i, O_NOM, O_DENOM>> {
251 Rate::<$i, O_NOM, O_DENOM>::const_try_from(self)
252 }
253
254 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1>::from_raw(1);")]
259 #[doc = concat!("let d1: Option<Duration::<", stringify!($i), ", 1, 1_000>> = r1.try_into_duration();")]
260 pub const fn try_into_duration<const O_NOM: u32, const O_DENOM: u32>(
264 self,
265 ) -> Option<Duration<$i, O_NOM, O_DENOM>> {
266 Duration::<$i, O_NOM, O_DENOM>::try_from_rate(self)
267 }
268
269 pub const fn into_duration<const O_NOM: u32, const O_DENOM: u32>(
271 self,
272 ) -> Duration<$i, O_NOM, O_DENOM> {
273 if let Some(v) = self.try_into_duration() {
274 v
275 } else {
276 panic!("Into duration failed, divide-by-zero!");
277 }
278 }
279
280 #[doc = concat!("let d1 = Duration::<", stringify!($i), ", 1, 1_000>::from_ticks(2);")]
285 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 1>::try_from_duration(d1);")]
286 #[inline]
290 pub const fn try_from_duration<const I_NOM: u32, const I_DENOM: u32>(
291 duration: Duration<$i, I_NOM, I_DENOM>,
292 ) -> Option<Self> {
293 if duration.ticks > 0 {
294 Some(Self::from_raw(
295 Helpers::<I_NOM, I_DENOM, NOM, DENOM>::RATE_TO_DURATION_NUMERATOR as $i
296 / duration.ticks
297 ))
298 } else {
299 None
300 }
301 }
302
303 #[inline]
305 pub const fn from_duration<const I_NOM: u32, const I_DENOM: u32>(
306 duration: Duration<$i, I_NOM, I_DENOM>,
307 ) -> Self {
308 if let Some(v) = Self::try_from_duration(duration) {
309 v
310 } else {
311 panic!("From duration failed, divide-by-zero!");
312 }
313 }
314
315 #[doc = concat!("let r1 = Rate::<", stringify!($i), ", 1, 100>::from_raw(1);")]
322 #[doc = concat!("let r2: Rate::<", stringify!($i), ", 1, 1_000> = r1.convert();")]
323 #[doc = concat!("const RAW: ", stringify!($i), "= ", stringify!($i), "::MAX - 10;")]
332 #[doc = concat!("const R1: Rate::<", stringify!($i), ", 1, 100> = Rate::<", stringify!($i), ", 1, 100>::from_raw(RAW);")]
333 #[doc = concat!("const R2: Rate::<", stringify!($i), ", 1, 200> = R1.convert();")]
335 pub const fn convert<const O_NOM: u32, const O_DENOM: u32>(
337 self,
338 ) -> Rate<$i, O_NOM, O_DENOM> {
339 if let Some(v) = self.const_try_into() {
340 v
341 } else {
342 panic!("Convert failed!");
343 }
344 }
345
346 #[inline]
348 #[allow(non_snake_case)]
349 pub const fn to_Hz(&self) -> $i {
350 (Helpers::<1, 1, NOM, DENOM>::LD_TIMES_RN as $i * self.raw)
351 / Helpers::<1, 1, NOM, DENOM>::RD_TIMES_LN as $i
352 }
353
354 #[inline]
356 #[allow(non_snake_case)]
357 pub const fn to_kHz(&self) -> $i {
358 (Helpers::<1_000, 1, NOM, DENOM>::LD_TIMES_RN as $i * self.raw)
359 / Helpers::<1_000, 1, NOM, DENOM>::RD_TIMES_LN as $i
360 }
361
362 #[inline]
364 #[allow(non_snake_case)]
365 pub const fn to_MHz(&self) -> $i {
366 (Helpers::<1_000_000, 1, NOM, DENOM>::LD_TIMES_RN as $i * self.raw)
367 / Helpers::<1_000_000, 1, NOM, DENOM>::RD_TIMES_LN as $i
368 }
369
370 #[inline]
372 #[allow(non_snake_case)]
373 pub const fn Hz(val: $i) -> Self {
374 Self::from_raw(
375 (Helpers::<1, 1, NOM, DENOM>::RD_TIMES_LN as $i * val)
376 / Helpers::<1, 1, NOM, DENOM>::LD_TIMES_RN as $i,
377 )
378 }
379
380 #[inline]
382 #[allow(non_snake_case)]
383 pub const fn kHz(val: $i) -> Self {
384 Self::from_raw(
385 (Helpers::<1_000, 1, NOM, DENOM>::RD_TIMES_LN as $i * val)
386 / Helpers::<1_000, 1, NOM, DENOM>::LD_TIMES_RN as $i,
387 )
388 }
389
390 #[inline]
392 #[allow(non_snake_case)]
393 pub const fn MHz(val: $i) -> Self {
394 Self::from_raw(
395 (Helpers::<1_000_000, 1, NOM, DENOM>::RD_TIMES_LN as $i * val)
396 / Helpers::<1_000_000, 1, NOM, DENOM>::LD_TIMES_RN as $i,
397 )
398 }
399
400 #[inline]
402 pub const fn nanos(val: $i) -> Self {
403 Self::from_duration(crate::Duration::<$i, 1, 1_000_000_000>::from_ticks(val))
404 }
405
406 #[inline]
408 pub const fn micros(val: $i) -> Self {
409 Self::from_duration(crate::Duration::<$i, 1, 1_000_000>::from_ticks(val))
410 }
411
412 #[inline]
414 pub const fn millis(val: $i) -> Self {
415 Self::from_duration(crate::Duration::<$i, 1, 1_000>::from_ticks(val))
416 }
417 }
418
419 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
420 PartialOrd<Rate<$i, R_NOM, R_DENOM>> for Rate<$i, L_NOM, L_DENOM>
421 {
422 #[inline]
423 fn partial_cmp(&self, other: &Rate<$i, R_NOM, R_DENOM>) -> Option<Ordering> {
424 self.const_partial_cmp(*other)
425 }
426 }
427
428 impl<const NOM: u32, const DENOM: u32> Ord for Rate<$i, NOM, DENOM> {
429 #[inline]
430 fn cmp(&self, other: &Self) -> Ordering {
431 Self::_const_cmp(self.raw, other.raw)
432 }
433 }
434
435 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
436 PartialEq<Rate<$i, R_NOM, R_DENOM>> for Rate<$i, L_NOM, L_DENOM>
437 {
438 #[inline]
439 fn eq(&self, other: &Rate<$i, R_NOM, R_DENOM>) -> bool {
440 self.const_eq(*other)
441 }
442 }
443
444 impl<const NOM: u32, const DENOM: u32> Eq for Rate<$i, NOM, DENOM> {}
445
446 impl<const NOM: u32, const DENOM: u32> ops::Sub<Rate<$i, NOM, DENOM>>
449 for Rate<$i, NOM, DENOM>
450 {
451 type Output = Rate<$i, NOM, DENOM>;
452
453 #[inline]
454 fn sub(self, other: Rate<$i, NOM, DENOM>) -> Self::Output {
455 if let Some(v) = self.checked_sub(other) {
456 v
457 } else {
458 panic!("Sub failed!");
459 }
460 }
461 }
462
463 impl<const NOM: u32, const DENOM: u32> ops::Add<Rate<$i, NOM, DENOM>>
466 for Rate<$i, NOM, DENOM>
467 {
468 type Output = Rate<$i, NOM, DENOM>;
469
470 #[inline]
471 fn add(self, other: Rate<$i, NOM, DENOM>) -> Self::Output {
472 if let Some(v) = self.checked_add(other) {
473 v
474 } else {
475 panic!("Add failed!");
476 }
477 }
478 }
479
480 impl<const NOM: u32, const DENOM: u32> ops::AddAssign<Rate<$i, NOM, DENOM>>
482 for Rate<$i, NOM, DENOM>
483 {
484 #[inline]
485 fn add_assign(&mut self, other: Self) {
486 *self = *self + other;
487 }
488 }
489
490 impl<const NOM: u32, const DENOM: u32> ops::Mul<Rate<$i, NOM, DENOM>> for u32 {
492 type Output = Rate<$i, NOM, DENOM>;
493
494 #[inline]
495 fn mul(self, mut other: Rate<$i, NOM, DENOM>) -> Self::Output {
496 other.raw *= self as $i;
497 other
498 }
499 }
500
501 impl<const NOM: u32, const DENOM: u32> ops::Mul<u32> for Rate<$i, NOM, DENOM> {
503 type Output = Rate<$i, NOM, DENOM>;
504
505 #[inline]
506 fn mul(mut self, other: u32) -> Self::Output {
507 self.raw *= other as $i;
508 self
509 }
510 }
511
512 impl<const NOM: u32, const DENOM: u32> ops::MulAssign<u32>
514 for Rate<$i, NOM, DENOM>
515 {
516 #[inline]
517 fn mul_assign(&mut self, other: u32) {
518 *self = *self * other;
519 }
520 }
521
522 impl<const NOM: u32, const DENOM: u32> ops::Div<u32> for Rate<$i, NOM, DENOM> {
524 type Output = Rate<$i, NOM, DENOM>;
525
526 #[inline]
527 fn div(mut self, other: u32) -> Self::Output {
528 self.raw /= other as $i;
529 self
530 }
531 }
532
533 impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32> ops::Div<Rate<$i, R_NOM, R_DENOM>>
535 for Rate<$i, L_NOM, L_DENOM>
536 {
537 type Output = $i;
538
539 #[inline]
540 fn div(self, other: Rate<$i, R_NOM, R_DENOM>) -> Self::Output {
541 let conv: Rate<$i, R_NOM, R_DENOM> = self.convert();
542 conv.raw / other.raw
543 }
544 }
545
546 impl<const NOM: u32, const DENOM: u32> ops::DivAssign<u32>
548 for Rate<$i, NOM, DENOM>
549 {
550 #[inline]
551 fn div_assign(&mut self, other: u32) {
552 *self = *self / other;
553 }
554 }
555
556 #[cfg(feature = "defmt")]
557 impl<const NOM: u32, const DENOM: u32> defmt::Format for Rate<$i, NOM, DENOM>
558 {
559 fn format(&self, f: defmt::Formatter) {
560 if NOM == 1 && DENOM == 1 {
561 defmt::write!(f, "{} Hz", self.raw)
562 } else if NOM == 1_000 && DENOM == 1 {
563 defmt::write!(f, "{} kHz", self.raw)
564 } else if NOM == 1_000_000 && DENOM == 1 {
565 defmt::write!(f, "{} MHz", self.raw)
566 } else if NOM == 1_000_000_000 && DENOM == 1 {
567 defmt::write!(f, "{} GHz", self.raw)
568 } else {
569 defmt::write!(f, "{} raw @ ({}/{})", self.raw, NOM, DENOM)
570 }
571 }
572 }
573
574 impl<const NOM: u32, const DENOM: u32> core::fmt::Display for Rate<$i, NOM, DENOM> {
575 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
576 if NOM == 1 && DENOM == 1 {
577 write!(f, "{} Hz", self.raw)
578 } else if NOM == 1_000 && DENOM == 1 {
579 write!(f, "{} kHz", self.raw)
580 } else if NOM == 1_000_000 && DENOM == 1 {
581 write!(f, "{} MHz", self.raw)
582 } else if NOM == 1_000_000_000 && DENOM == 1 {
583 write!(f, "{} GHz", self.raw)
584 } else {
585 write!(f, "{} raw @ ({}/{})", self.raw, NOM, DENOM)
586 }
587 }
588 }
589 };
590}
591
592impl_rate_for_integer!(u32);
593impl_rate_for_integer!(u64);
594
595impl<const NOM: u32, const DENOM: u32> From<Rate<u32, NOM, DENOM>> for Rate<u64, NOM, DENOM> {
600 #[inline]
601 fn from(val: Rate<u32, NOM, DENOM>) -> Rate<u64, NOM, DENOM> {
602 Rate::<u64, NOM, DENOM>::from_raw(val.raw() as u64)
603 }
604}
605
606impl<const NOM: u32, const DENOM: u32> convert::TryFrom<Rate<u64, NOM, DENOM>>
607 for Rate<u32, NOM, DENOM>
608{
609 type Error = ();
610
611 #[inline]
612 fn try_from(val: Rate<u64, NOM, DENOM>) -> Result<Rate<u32, NOM, DENOM>, ()> {
613 Ok(Rate::<u32, NOM, DENOM>::from_raw(
614 val.raw().try_into().map_err(|_| ())?,
615 ))
616 }
617}
618
619impl<const NOM: u32, const DENOM: u32> ops::Sub<Rate<u32, NOM, DENOM>> for Rate<u64, NOM, DENOM> {
622 type Output = Rate<u64, NOM, DENOM>;
623
624 #[inline]
625 fn sub(self, other: Rate<u32, NOM, DENOM>) -> Self::Output {
626 if let Some(v) = self.checked_sub(Rate::<u64, NOM, DENOM>::from_raw(other.raw() as u64)) {
627 v
628 } else {
629 panic!("Sub failed!");
630 }
631 }
632}
633
634impl<const NOM: u32, const DENOM: u32> ops::SubAssign<Rate<u32, NOM, DENOM>>
636 for Rate<u64, NOM, DENOM>
637{
638 #[inline]
639 fn sub_assign(&mut self, other: Rate<u32, NOM, DENOM>) {
640 *self = *self - other;
641 }
642}
643
644impl<const NOM: u32, const DENOM: u32> ops::Add<Rate<u32, NOM, DENOM>> for Rate<u64, NOM, DENOM> {
647 type Output = Rate<u64, NOM, DENOM>;
648
649 #[inline]
650 fn add(self, other: Rate<u32, NOM, DENOM>) -> Self::Output {
651 if let Some(v) = self.checked_add(Rate::<u64, NOM, DENOM>::from_raw(other.raw() as u64)) {
652 v
653 } else {
654 panic!("Add failed!");
655 }
656 }
657}
658
659impl<const NOM: u32, const DENOM: u32> ops::AddAssign<Rate<u32, NOM, DENOM>>
661 for Rate<u64, NOM, DENOM>
662{
663 #[inline]
664 fn add_assign(&mut self, other: Rate<u32, NOM, DENOM>) {
665 *self = *self + other;
666 }
667}
668
669impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
670 PartialOrd<Rate<u32, R_NOM, R_DENOM>> for Rate<u64, L_NOM, L_DENOM>
671{
672 #[inline]
673 fn partial_cmp(&self, other: &Rate<u32, R_NOM, R_DENOM>) -> Option<Ordering> {
674 self.partial_cmp(&Rate::<u64, R_NOM, R_DENOM>::from_raw(other.raw() as u64))
675 }
676}
677
678impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
679 PartialEq<Rate<u32, R_NOM, R_DENOM>> for Rate<u64, L_NOM, L_DENOM>
680{
681 #[inline]
682 fn eq(&self, other: &Rate<u32, R_NOM, R_DENOM>) -> bool {
683 self.eq(&Rate::<u64, R_NOM, R_DENOM>::from_raw(other.raw() as u64))
684 }
685}
686
687impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
688 PartialOrd<Rate<u64, R_NOM, R_DENOM>> for Rate<u32, L_NOM, L_DENOM>
689{
690 #[inline]
691 fn partial_cmp(&self, other: &Rate<u64, R_NOM, R_DENOM>) -> Option<Ordering> {
692 Rate::<u64, L_NOM, L_DENOM>::from_raw(self.raw as u64).partial_cmp(other)
693 }
694}
695
696impl<const L_NOM: u32, const L_DENOM: u32, const R_NOM: u32, const R_DENOM: u32>
697 PartialEq<Rate<u64, R_NOM, R_DENOM>> for Rate<u32, L_NOM, L_DENOM>
698{
699 #[inline]
700 fn eq(&self, other: &Rate<u64, R_NOM, R_DENOM>) -> bool {
701 Rate::<u64, L_NOM, L_DENOM>::from_raw(self.raw as u64).eq(other)
702 }
703}
704
705pub trait ExtU32 {
707 #[allow(non_snake_case)]
709 fn Hz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM>;
710
711 #[allow(non_snake_case)]
713 fn kHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM>;
714
715 #[allow(non_snake_case)]
717 fn MHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM>;
718}
719
720impl ExtU32 for u32 {
721 #[inline]
722 #[allow(non_snake_case)]
723 fn Hz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM> {
724 Rate::<u32, NOM, DENOM>::Hz(self)
725 }
726
727 #[inline]
728 #[allow(non_snake_case)]
729 fn kHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM> {
730 Rate::<u32, NOM, DENOM>::kHz(self)
731 }
732
733 #[inline]
734 #[allow(non_snake_case)]
735 fn MHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u32, NOM, DENOM> {
736 Rate::<u32, NOM, DENOM>::MHz(self)
737 }
738}
739
740pub trait ExtU64 {
742 #[allow(non_snake_case)]
744 fn Hz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM>;
745
746 #[allow(non_snake_case)]
748 fn kHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM>;
749
750 #[allow(non_snake_case)]
752 fn MHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM>;
753}
754
755impl ExtU64 for u64 {
756 #[inline]
757 #[allow(non_snake_case)]
758 fn Hz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM> {
759 Rate::<u64, NOM, DENOM>::Hz(self)
760 }
761
762 #[inline]
763 #[allow(non_snake_case)]
764 fn kHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM> {
765 Rate::<u64, NOM, DENOM>::kHz(self)
766 }
767
768 #[inline]
769 #[allow(non_snake_case)]
770 fn MHz<const NOM: u32, const DENOM: u32>(self) -> Rate<u64, NOM, DENOM> {
771 Rate::<u64, NOM, DENOM>::MHz(self)
772 }
773}