measures/
traits.rs

1use core::fmt;
2use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
3
4pub trait Pow {
5    fn powf(self, exponent: Self) -> Self;
6}
7impl Pow for f32 {
8    fn powf(self, exponent: Self) -> Self {
9        self.powf(exponent)
10    }
11}
12impl Pow for f64 {
13    fn powf(self, exponent: Self) -> Self {
14        self.powf(exponent)
15    }
16}
17
18pub trait FromF64 {
19    fn from_f64(n: f64) -> Self;
20}
21impl FromF64 for f32 {
22    fn from_f64(n: f64) -> Self {
23        n as f32
24    }
25}
26impl FromF64 for f64 {
27    fn from_f64(n: f64) -> Self {
28        n
29    }
30}
31
32pub trait Sqrt {
33    type Output;
34    fn sqrt(self) -> Self::Output;
35}
36impl Sqrt for f32 {
37    type Output = f32;
38    fn sqrt(self) -> Self {
39        self.sqrt()
40    }
41}
42impl Sqrt for f64 {
43    type Output = f64;
44    fn sqrt(self) -> Self {
45        self.sqrt()
46    }
47}
48
49pub trait CubicRoot {
50    type Output;
51    fn cubic_root(self) -> Self::Output;
52}
53impl CubicRoot for f32 {
54    type Output = f32;
55    fn cubic_root(self) -> Self {
56        self.powf(1. / 3.)
57    }
58}
59impl CubicRoot for f64 {
60    type Output = f64;
61    fn cubic_root(self) -> Self {
62        self.powf(1. / 3.)
63    }
64}
65
66pub trait Trigonometry {
67    type Output;
68    fn cos(self) -> Self::Output;
69    fn sin(self) -> Self::Output;
70    fn tan(self) -> Self::Output;
71    fn sin_cos(self) -> (Self::Output, Self::Output);
72}
73impl Trigonometry for f32 {
74    type Output = f32;
75    fn cos(self) -> Self::Output {
76        self.cos()
77    }
78    fn sin(self) -> Self::Output {
79        self.sin()
80    }
81    fn tan(self) -> Self::Output {
82        self.tan()
83    }
84    fn sin_cos(self) -> (Self::Output, Self::Output) {
85        self.sin_cos()
86    }
87}
88impl Trigonometry for f64 {
89    type Output = f64;
90    fn cos(self) -> Self::Output {
91        self.cos()
92    }
93    fn sin(self) -> Self::Output {
94        self.sin()
95    }
96    fn tan(self) -> Self::Output {
97        self.tan()
98    }
99    fn sin_cos(self) -> (Self::Output, Self::Output) {
100        self.sin_cos()
101    }
102}
103
104pub trait InverseTrigonometry {
105    type Output;
106    fn acos(self) -> Self::Output;
107    fn asin(self) -> Self::Output;
108    fn atan2(self, other: Self) -> Self::Output;
109}
110impl InverseTrigonometry for f32 {
111    type Output = f32;
112    fn acos(self) -> Self::Output {
113        self.acos()
114    }
115    fn asin(self) -> Self::Output {
116        self.asin()
117    }
118    fn atan2(self, other: Self) -> Self::Output {
119        self.atan2(other)
120    }
121}
122impl InverseTrigonometry for f64 {
123    type Output = f64;
124    fn acos(self) -> Self::Output {
125        self.acos()
126    }
127    fn asin(self) -> Self::Output {
128        self.asin()
129    }
130    fn atan2(self, other: Self) -> Self::Output {
131        self.atan2(other)
132    }
133}
134
135pub trait Decibel {
136    fn to_decibels(self) -> Self;
137    fn decibels_to_value(self) -> Self;
138}
139impl Decibel for f32 {
140    fn to_decibels(self) -> Self {
141        self.log10() * 10.
142    }
143    fn decibels_to_value(self) -> Self {
144        10_f32.powf(self * 0.1)
145    }
146}
147impl Decibel for f64 {
148    fn to_decibels(self) -> Self {
149        self.log10() * 10.
150    }
151    fn decibels_to_value(self) -> Self {
152        10_f64.powf(self * 0.1)
153    }
154}
155
156pub trait HasZero {
157    const ZERO: Self;
158}
159impl HasZero for f32 {
160    const ZERO: Self = 0.;
161}
162impl HasZero for f64 {
163    const ZERO: Self = 0.;
164}
165
166pub trait HasOne {
167    const ONE: Self;
168}
169impl HasOne for f32 {
170    const ONE: Self = 1.;
171}
172impl HasOne for f64 {
173    const ONE: Self = 1.;
174}
175
176pub trait HasHalf {
177    const HALF: Self;
178}
179impl HasHalf for f32 {
180    const HALF: Self = 0.5;
181}
182impl HasHalf for f64 {
183    const HALF: Self = 0.5;
184}
185
186pub trait HasSign {
187    fn signum(self) -> Self;
188    fn abs(self) -> Self;
189}
190impl HasSign for f32 {
191    fn signum(self) -> Self {
192        self.signum()
193    }
194    fn abs(self) -> Self {
195        self.abs()
196    }
197}
198impl HasSign for f64 {
199    fn signum(self) -> Self {
200        self.signum()
201    }
202    fn abs(self) -> Self {
203        self.abs()
204    }
205}
206
207pub trait ArithmeticOps:
208    Neg<Output = Self>
209    + Add<Self, Output = Self>
210    + AddAssign<Self>
211    + Sub<Self, Output = Self>
212    + SubAssign<Self>
213    + Mul<Self, Output = Self>
214    + MulAssign<Self>
215    + Div<Self, Output = Self>
216    + DivAssign<Self>
217    + Rem<Self, Output = Self>
218    + Pow
219    + FromF64
220    + Sqrt<Output = Self>
221    + CubicRoot<Output = Self>
222    + Trigonometry<Output = Self>
223    + InverseTrigonometry<Output = Self>
224    + Decibel
225    + HasZero
226    + HasOne
227    + HasHalf
228    + HasSign
229    + std::iter::Sum
230    + fmt::Display
231    + fmt::Debug
232    + Clone
233    + Copy
234    + PartialOrd
235    + PartialEq
236where
237    Self: std::marker::Sized,
238{
239}
240
241impl<T> ArithmeticOps for T where
242    T: Neg<Output = Self>
243        + Add<T, Output = T>
244        + AddAssign<T>
245        + Sub<T, Output = Self>
246        + SubAssign<T>
247        + Mul<T, Output = Self>
248        + MulAssign<T>
249        + Div<T, Output = Self>
250        + DivAssign<T>
251        + Rem<T, Output = Self>
252        + Pow
253        + FromF64
254        + Sqrt<Output = Self>
255        + CubicRoot<Output = Self>
256        + Trigonometry<Output = Self>
257        + InverseTrigonometry<Output = Self>
258        + Decibel
259        + HasZero
260        + HasOne
261        + HasHalf
262        + HasSign
263        + std::iter::Sum
264        + fmt::Display
265        + fmt::Debug
266        + Clone
267        + Copy
268        + PartialOrd
269        + PartialEq
270{
271}
272
273/*
274trait Vector<Number>:
275    Add<Self, Output = Self>
276    + AddAssign<Self>
277    + Sub<Self, Output = Self>
278    + SubAssign<Self>
279    + Mul<Number, Output = Self>
280    + MulAssign<Number>
281    + Div<Number, Output = Self>
282    + DivAssign<Number>
283    + Sized
284{
285}
286
287trait Affine<Number, V: Vector<Number>>:
288    Add<V, Output = Self> + AddAssign<V> + Sub<V, Output = Self> + SubAssign<V> + Sized
289{
290}
291*/
292
293pub trait LossyFrom<Source> {
294    fn lossy_from(n: Source) -> Self;
295}
296
297impl LossyFrom<f32> for f32 {
298    fn lossy_from(n: f32) -> Self {
299        n
300    }
301}
302impl LossyFrom<f32> for f64 {
303    fn lossy_from(n: f32) -> Self {
304        n as Self
305    }
306}
307impl LossyFrom<f64> for f32 {
308    fn lossy_from(n: f64) -> Self {
309        n as Self
310    }
311}
312impl LossyFrom<f64> for f64 {
313    fn lossy_from(n: f64) -> Self {
314        n
315    }
316}
317
318pub trait CrossProduct<Rhs = Self> {
319    type Output;
320    #[must_use]
321    fn cross_product(self, rhs: Rhs) -> Self::Output;
322}
323
324pub trait MeasurementUnit {
325    type Property: MeasurementProperty;
326    const RATIO: f64;
327    const OFFSET: f64;
328    const SUFFIX: &'static str;
329}
330
331pub trait AngleMeasurementUnit: MeasurementUnit<Property = crate::angle::Angle> {
332    const CYCLE_FRACTION: f64;
333}
334
335pub trait MeasurementProperty {}
336
337pub trait ScalarProperty: MeasurementProperty {}
338
339pub trait VectorProperty: MeasurementProperty {}