1use num::{Zero, complex::Complex};
13use uom::si::*;
14
15use super::{DynQuantity, F64RealOrComplex};
16use crate::error::{ConversionError, NotConvertibleFromComplexF64};
17use crate::unit::Unit;
18
19#[cfg(feature = "uom")]
20impl<L, M, T, I, Th, N, J, K> crate::unit::UnitFromType
21 for uom::si::Quantity<uom::si::ISQ<L, M, T, I, Th, N, J, K>, uom::si::SI<f64>, f64>
22where
23 L: uom::typenum::Integer,
24 M: uom::typenum::Integer,
25 T: uom::typenum::Integer,
26 I: uom::typenum::Integer,
27 Th: uom::typenum::Integer,
28 N: uom::typenum::Integer,
29 J: uom::typenum::Integer,
30 K: ?Sized,
31{
32 fn unit_from_type() -> Unit {
33 return Unit {
34 second: T::to_i32(),
35 meter: L::to_i32(),
36 kilogram: M::to_i32(),
37 ampere: I::to_i32(),
38 kelvin: Th::to_i32(),
39 mol: N::to_i32(),
40 candela: J::to_i32(),
41 };
42 }
43}
44
45impl<L, M, T, I, Th, N, J, K, V> TryFrom<DynQuantity<V>>
46 for uom::si::Quantity<uom::si::ISQ<L, M, T, I, Th, N, J, K>, uom::si::SI<f64>, f64>
47where
48 L: uom::typenum::Integer,
49 M: uom::typenum::Integer,
50 T: uom::typenum::Integer,
51 I: uom::typenum::Integer,
52 Th: uom::typenum::Integer,
53 N: uom::typenum::Integer,
54 J: uom::typenum::Integer,
55 K: ?Sized,
56 V: F64RealOrComplex,
57{
58 type Error = ConversionError;
59
60 fn try_from(quantity: DynQuantity<V>) -> Result<Self, Self::Error> {
61 let expected = Unit {
63 second: T::to_i32(),
64 meter: L::to_i32(),
65 kilogram: M::to_i32(),
66 ampere: I::to_i32(),
67 kelvin: Th::to_i32(),
68 mol: N::to_i32(),
69 candela: J::to_i32(),
70 };
71 if expected != quantity.unit {
72 return Err(ConversionError::UnitMismatch {
73 expected,
74 found: quantity.unit,
75 });
76 }
77
78 let value = quantity.value.to_complexf64();
81
82 if !value.im.is_zero() {
84 return Err(ConversionError::NotConvertibleFromComplexF64(
85 NotConvertibleFromComplexF64 {
86 source: value,
87 target_type: "f64",
88 },
89 ));
90 }
91
92 return Ok(uom::si::Quantity {
93 dimension: std::marker::PhantomData,
94 units: std::marker::PhantomData,
95 value: value.re,
96 });
97 }
98}
99
100impl<L, M, T, I, Th, N, J, K, V> TryFrom<DynQuantity<V>>
101 for uom::si::Quantity<
102 uom::si::ISQ<L, M, T, I, Th, N, J, K>,
103 uom::si::SI<Complex<f64>>,
104 Complex<f64>,
105 >
106where
107 L: uom::typenum::Integer,
108 M: uom::typenum::Integer,
109 T: uom::typenum::Integer,
110 I: uom::typenum::Integer,
111 Th: uom::typenum::Integer,
112 N: uom::typenum::Integer,
113 J: uom::typenum::Integer,
114 K: ?Sized,
115 V: F64RealOrComplex,
116{
117 type Error = ConversionError;
118
119 fn try_from(quantity: DynQuantity<V>) -> Result<Self, Self::Error> {
120 let expected = Unit {
122 second: T::to_i32(),
123 meter: L::to_i32(),
124 kilogram: M::to_i32(),
125 ampere: I::to_i32(),
126 kelvin: Th::to_i32(),
127 mol: N::to_i32(),
128 candela: J::to_i32(),
129 };
130 if expected != quantity.unit {
131 return Err(ConversionError::UnitMismatch {
132 expected,
133 found: quantity.unit,
134 });
135 }
136
137 let value = quantity.value.to_complexf64();
141
142 return Ok(uom::si::Quantity {
143 dimension: std::marker::PhantomData,
144 units: std::marker::PhantomData,
145 value,
146 });
147 }
148}
149
150impl<L, M, T, I, Th, N, J, K, V>
151 From<uom::si::Quantity<uom::si::ISQ<L, M, T, I, Th, N, J, K>, uom::si::SI<f64>, f64>>
152 for DynQuantity<V>
153where
154 L: uom::typenum::Integer,
155 M: uom::typenum::Integer,
156 T: uom::typenum::Integer,
157 I: uom::typenum::Integer,
158 Th: uom::typenum::Integer,
159 N: uom::typenum::Integer,
160 J: uom::typenum::Integer,
161 K: ?Sized,
162 V: F64RealOrComplex,
163{
164 fn from(
165 quantitiy: uom::si::Quantity<uom::si::ISQ<L, M, T, I, Th, N, J, K>, uom::si::SI<f64>, f64>,
166 ) -> Self {
167 let exponents = Unit {
168 second: T::to_i32(),
169 meter: L::to_i32(),
170 kilogram: M::to_i32(),
171 ampere: I::to_i32(),
172 kelvin: Th::to_i32(),
173 mol: N::to_i32(),
174 candela: J::to_i32(),
175 };
176 return DynQuantity::new(V::from_f64(quantitiy.value), exponents);
177 }
178}
179
180impl<L, M, T, I, Th, N, J, K, V>
181 TryFrom<
182 uom::si::Quantity<
183 uom::si::ISQ<L, M, T, I, Th, N, J, K>,
184 uom::si::SI<Complex<f64>>,
185 Complex<f64>,
186 >,
187 > for DynQuantity<V>
188where
189 L: uom::typenum::Integer,
190 M: uom::typenum::Integer,
191 T: uom::typenum::Integer,
192 I: uom::typenum::Integer,
193 Th: uom::typenum::Integer,
194 N: uom::typenum::Integer,
195 J: uom::typenum::Integer,
196 K: ?Sized,
197 V: F64RealOrComplex,
198{
199 type Error = NotConvertibleFromComplexF64;
200
201 fn try_from(
202 quantitiy: uom::si::Quantity<
203 uom::si::ISQ<L, M, T, I, Th, N, J, K>,
204 uom::si::SI<Complex<f64>>,
205 Complex<f64>,
206 >,
207 ) -> Result<Self, Self::Error> {
208 let value = V::try_from_complexf64(quantitiy.value)?;
209
210 let exponents = Unit {
211 second: T::to_i32(),
212 meter: L::to_i32(),
213 kilogram: M::to_i32(),
214 ampere: I::to_i32(),
215 kelvin: Th::to_i32(),
216 mol: N::to_i32(),
217 candela: J::to_i32(),
218 };
219 return Ok(DynQuantity::new(value, exponents));
220 }
221}