reda_unit/unit/
ops.rs

1use crate::Number;
2use std::{cmp::Ordering, ops::{Add, Div, Mul, Neg, Rem, Sub}};
3use paste::paste;
4use crate::unit::units::*;
5
6use super::{Unit, UnitNumber};
7
8/// output = lhs * rhs
9#[macro_export]
10macro_rules! impl_mul {
11    ($output:ty, $lhs:ty, $rhs:ty) => {
12        paste! {
13            impl std::ops::Mul<crate::UnitNumber<[<$rhs Unit>]>> for crate::UnitNumber<[<$lhs Unit>]> {
14                type Output = crate::UnitNumber<[<$output Unit>]>;
15                fn mul(self, rhs: crate::UnitNumber<[<$rhs Unit>]>) -> Self::Output {
16                    let result = self.number * rhs.number;
17                    crate::UnitNumber::new(result)
18                }
19            }
20        }
21    };
22}
23
24/// output = lhs / rhs
25#[macro_export]
26macro_rules! impl_div {
27    ($output:ty, $lhs:ty, $rhs:ty) => {
28        paste! {
29            impl std::ops::Div<crate::UnitNumber<[<$rhs Unit>]>> for crate::UnitNumber<[<$lhs Unit>]> {
30                type Output = crate::UnitNumber<[<$output Unit>]>;
31                fn div(self, rhs: crate::UnitNumber<[<$rhs Unit>]>) -> Self::Output {
32                    let result = self.number / rhs.number;
33                    crate::UnitNumber::new(result)
34                }
35            }
36        }
37    };
38}
39
40/// output = lhs * rhs
41/// lhs = output / rhs
42/// rhs = output / lhs
43#[macro_export]
44macro_rules! define_rule {
45    ($output:ty, $lhs:ty, $rhs:ty) => {
46        impl_mul!($output, $lhs, $rhs);
47        impl_div!($lhs, $output, $rhs);
48        impl_div!($rhs, $output, $lhs);
49    };
50}
51
52define_rule!(Voltage, Resistance, Current);    // V = R × I
53define_rule!(Power, Voltage, Current);         // P = V × I
54define_rule!(Energy, Power, Time);             // E = P × t
55define_rule!(Charge, Capacitance, Voltage);    // Q = C × V
56define_rule!(Charge, Current, Time);           // Q = C × V
57define_rule!(Current, Charge, Time);           // Q = I × t
58define_rule!(Length, Velocity, Time);          // S = V × T
59 
60define_rule!(Power, Force, Velocity);          // P = F × v
61define_rule!(Energy, Force, Length);           // E = F × d
62define_rule!(Force, Pressure, Area);           // F = P × A
63
64define_rule!(MagneticFlux, FluxDensity, Area); // Φ = B × A
65define_rule!(MagneticFlux, Voltage, Time);     // Φ = V × t
66
67impl_mul!(Area, Length, Length);
68impl_div!(Length, Area, Length);
69
70impl Frequency {
71    pub fn to_period(&self) -> Time {
72        Time::new(1. / self.number)
73    }
74}
75
76impl Time {
77    pub fn to_frquency(&self) -> Frequency {
78        Frequency::new(1. / self.number)
79    }
80}
81
82impl Mul<Time> for Frequency {
83    type Output = Number;
84    fn mul(self, rhs: Time) -> Self::Output {
85        self.value() * rhs.value()
86    }
87}
88
89impl Mul<Frequency> for Time {
90    type Output = Number;
91    fn mul(self, rhs: Frequency) -> Self::Output {
92        self.value() * rhs.value()
93    }
94}
95
96impl<U: Unit> Div<UnitNumber<U>> for UnitNumber<U> {
97    type Output = Number;
98    fn div(self, rhs: UnitNumber<U>) -> Self::Output {
99        self.value() / rhs.value()
100    }
101}
102
103// UnitNumber<U> = UnitNumber<U> + UnitNumber<U>
104impl<U: Unit> Add<UnitNumber<U>> for UnitNumber<U> {
105    type Output = UnitNumber<U>;
106    fn add(self, rhs: UnitNumber<U>) -> Self::Output {
107        let n = self.number + rhs.number;
108        Self::Output::new(n)
109    }
110}
111
112// UnitNumber<U> = UnitNumber<U> - UnitNumber<U>
113impl<U: Unit> Sub<UnitNumber<U>> for UnitNumber<U> {
114    type Output = Self;
115    fn sub(self, rhs: Self) -> Self::Output {
116        let n = self.number - rhs.number;
117        Self::Output::new(n)
118    }
119}
120
121// UnitNumber<U> = - UnitNumber<U>
122impl<U: Unit> Neg for UnitNumber<U> {
123    type Output = Self;
124    fn neg(self) -> Self::Output {
125        UnitNumber::new(self.number.neg())
126    }
127}
128
129// UnitNumber<U> = UnitNumber<U> * Number
130impl<U: Unit> Mul<Number> for UnitNumber<U> {
131    type Output = Self;
132    fn mul(self, rhs: Number) -> Self {
133        let lhs_val = self.number.to_f64();
134        let rhs_val = rhs.to_f64();
135        Self::new(Number::from_f64(lhs_val * rhs_val))
136    }
137}
138
139// UnitNumber<U> = Number * UnitNumber<U>
140impl<U: Unit> Mul<UnitNumber<U>> for Number {
141    type Output = UnitNumber<U>;
142    fn mul(self, rhs: UnitNumber<U>) -> UnitNumber<U> {
143        rhs * self
144    }
145}
146
147// UnitNumber<U> = UnitNumber<U> * f64
148impl<U: Unit> Mul<f64> for UnitNumber<U> {
149    type Output = Self;
150    fn mul(self, rhs: f64) -> Self {
151        let lhs_val = self.number.to_f64();
152        Self::new(Number::from_f64(lhs_val * rhs))
153    }
154}
155
156// UnitNumber<U> = Number * UnitNumber<U>
157impl<U: Unit> Mul<UnitNumber<U>> for f64 {
158    type Output = UnitNumber<U>;
159    fn mul(self, rhs: UnitNumber<U>) -> UnitNumber<U> {
160        rhs * self
161    }
162}
163
164// UnitNumber<U> = UnitNumber<U> / Number
165impl<U: Unit> Div<Number> for UnitNumber<U> {
166    type Output = Self;
167    fn div(self, rhs: Number) -> Self {
168        let lhs_val = self.number.to_f64();
169        let rhs_val = rhs.to_f64();
170        Self::new(Number::from_f64(lhs_val / rhs_val))
171    }
172}
173
174// UnitNumber<U> = UnitNumber<U> / f64
175impl<U: Unit> Div<f64> for UnitNumber<U> {
176    type Output = Self;
177    fn div(self, rhs: f64) -> Self {
178        let lhs_val = self.number.to_f64();
179        Self::new(Number::from_f64(lhs_val / rhs))
180    }
181}
182
183impl<U: Unit> Rem<UnitNumber<U>> for UnitNumber<U> {
184    type Output = Self;
185    fn rem(self, rhs: UnitNumber<U>) -> Self::Output {
186        Self::new(self.number % rhs.number)
187    }
188}
189
190//==================== Cmp and Eq =========================//
191
192impl<U: Unit> PartialOrd for UnitNumber<U> {
193    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
194        self.number.partial_cmp(&other.number)
195    }
196}
197
198impl<U: Unit> Ord for UnitNumber<U> {
199    fn cmp(&self, other: &Self) -> Ordering {
200        self.partial_cmp(other).unwrap()
201    }
202}
203