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#[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#[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#[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); define_rule!(Power, Voltage, Current); define_rule!(Energy, Power, Time); define_rule!(Charge, Capacitance, Voltage); define_rule!(Charge, Current, Time); define_rule!(Current, Charge, Time); define_rule!(Length, Velocity, Time); define_rule!(Power, Force, Velocity); define_rule!(Energy, Force, Length); define_rule!(Force, Pressure, Area); define_rule!(MagneticFlux, FluxDensity, Area); define_rule!(MagneticFlux, Voltage, Time); impl_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
103impl<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
112impl<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
121impl<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
129impl<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
139impl<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
147impl<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
156impl<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
164impl<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
174impl<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
190impl<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