spectrum_analyzer/
frequency.rs1use core::cmp::Ordering;
28use core::fmt::{Display, Formatter, Result};
29use core::ops::{Add, Div, Mul, Sub};
30
31pub type Frequency = OrderableF32;
33pub type FrequencyValue = OrderableF32;
36
37#[derive(Debug, Copy, Clone, Default)]
40pub struct OrderableF32(f32);
41
42impl OrderableF32 {
43 #[inline]
44 pub const fn val(&self) -> f32 {
45 self.0
46 }
47}
48
49impl From<f32> for OrderableF32 {
50 #[inline]
51 fn from(val: f32) -> Self {
52 debug_assert!(!val.is_nan(), "NaN-values are not supported!");
53 debug_assert!(!val.is_infinite(), "Infinite-values are not supported!");
54 Self(val)
55 }
56}
57
58impl Display for OrderableF32 {
59 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
60 write!(f, "{}", self.0)
61 }
62}
63
64impl Ord for OrderableF32 {
65 #[inline]
66 fn cmp(&self, other: &Self) -> Ordering {
67 if self.val() < other.val() {
68 Ordering::Less
69 } else if self.val() == other.val() {
70 Ordering::Equal
71 } else {
72 Ordering::Greater
73 }
74 }
75}
76
77impl Eq for OrderableF32 {}
78
79impl PartialEq for OrderableF32 {
80 #[inline]
81 fn eq(&self, other: &Self) -> bool {
82 matches!(self.cmp(other), Ordering::Equal)
83 }
84}
85
86impl PartialOrd for OrderableF32 {
87 #[allow(clippy::float_cmp)]
88 #[inline]
89 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
90 Some(self.cmp(other))
91 }
92}
93
94impl Add for OrderableF32 {
95 type Output = Self;
96
97 #[inline]
98 fn add(self, other: Self) -> Self::Output {
99 (self.val() + other.val()).into()
100 }
101}
102
103impl Sub for OrderableF32 {
104 type Output = Self;
105
106 #[inline]
107 fn sub(self, other: Self) -> Self::Output {
108 (self.val() - other.val()).into()
109 }
110}
111
112impl Mul for OrderableF32 {
113 type Output = Self;
114
115 #[inline]
116 fn mul(self, other: Self) -> Self::Output {
117 (self.val() * other.val()).into()
118 }
119}
120
121impl Div for OrderableF32 {
122 type Output = Self;
123
124 #[inline]
125 fn div(self, other: Self) -> Self::Output {
126 let quotient = self.val() / other.val();
127 debug_assert!(!quotient.is_nan(), "NaN is not allowed");
128 debug_assert!(!quotient.is_infinite(), "INFINITY is not allowed");
129 quotient.into()
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_orderablef32() {
139 let f1: OrderableF32 = (2.0_f32).into();
140 let f2: OrderableF32 = (-7.0_f32).into();
141
142 let f3 = f1 + f2;
143 let f4 = f1 - f2;
144
145 assert_eq!(-5.0, f3.val(), "add must work");
146 assert_eq!(9.0, f4.val(), "add must work");
147 assert!(f2 < f1, "Compare must work");
148 assert!(f1 > f2, "Compare must work");
149 #[allow(clippy::eq_op)]
150 {
151 assert_eq!(f1, f1, "Equal must work");
152 }
153 }
154}