1#[macro_export]
2macro_rules! impl_quantity_vec_ops {
3 ($quantity:ident) =>
4 {
5 paste::paste!
6 {
7 use core::ops::{Mul, Div, Add, Sub, AddAssign, SubAssign, MulAssign, DivAssign };
8 impl Div<f64> for [<$quantity Vec>]
9 {
10 type Output = [<$quantity Vec>];
11
12 fn div(self, rhs: f64) -> Self::Output {
13 let mut result = self.clone();
14 for val in result.values.as_mut_slice()
15 {
16 *val /= rhs;
17 }
18 result
19 }
20 }
21
22
23 impl Mul<f64> for [<$quantity Vec>]
24 {
25 type Output = [<$quantity Vec>];
26
27 fn mul(self, rhs: f64) -> Self::Output {
28 let mut result = self.clone();
29 for val in result.values.as_mut_slice()
30 {
31 *val *= rhs;
32 }
33 result
34 }
35 }
36 impl DivAssign<f64> for [<$quantity Vec>]
37 {
38
39 fn div_assign(&mut self, rhs: f64) {
40 for val in self.values.as_mut_slice()
41 {
42 *val /= rhs;
43 }
44 }
45 }
46 impl MulAssign<f64> for [<$quantity Vec>]
47 {
48
49 fn mul_assign(&mut self, rhs: f64) {
50 for val in self.values.as_mut_slice()
51 {
52 *val *= rhs;
53 }
54 }
55 }
56 use $crate::traits::Unit;
57 impl AddAssign<[<$quantity Vec>]> for [<$quantity Vec>]
58 {
59
60 fn add_assign(&mut self, rhs: [<$quantity Vec>]) {
61 if rhs.values.len() != self.values.len()
62 {
63 panic!("Slice dimensions do not match: {} != {}", rhs.values.len(), self.values.len());
64 }
65 let factor = rhs.unit.definition().convert_unchecked(self.unit.definition());
66 for (val, &rhs) in self.values.as_mut_slice().iter_mut().zip(rhs.values.as_slice())
67 {
68 *val += rhs*factor;
69 }
70 }
71 }
72 impl SubAssign<[<$quantity Vec>]> for [<$quantity Vec>]
73 {
74
75 fn sub_assign(&mut self, rhs: [<$quantity Vec>]) {
76 if rhs.values.len() != self.values.len()
77 {
78 panic!("Slice dimensions do not match: {} != {}", rhs.values.len(), self.values.len());
79 }
80 let factor = rhs.unit.convert_unchecked(self.unit);
81 for (val, &rhs) in self.values.as_mut_slice().iter_mut().zip(rhs.values.as_slice())
82 {
83 *val -= rhs*factor;
84 }
85 }
86 }
87 impl Add<[<$quantity Vec>]> for [<$quantity Vec>]
88 {
89 type Output=Self;
90
91 fn add(self, rhs: [<$quantity Vec>]) -> Self {
92 let mut result = self.clone();
93 result += rhs;
94 result
95 }
96 }
97 impl Sub<[<$quantity Vec>]> for [<$quantity Vec>]
98 {
99 type Output=Self;
100 fn sub(self, rhs: [<$quantity Vec>]) -> Self {
101 let mut result = self;
102 result -= rhs;
103 result
104 }
105 }
106 }
107 }
108}
109
110#[macro_export]
111macro_rules! impl_quantity_array_ops {
112 ($quantity:ident) =>
113 {
114 paste::paste!
115 {
116 impl<const N: usize> Div<f64> for [<$quantity Array>]<N>
117 {
118 type Output = [<$quantity Array>]<N>;
119
120 fn div(self, rhs: f64) -> Self::Output {
121 let mut result = self.clone();
122 for val in result.values.as_mut_slice()
123 {
124 *val /= rhs;
125 }
126 result
127 }
128 }
129
130
131 impl<const N: usize> Mul<f64> for [<$quantity Array>]<N>
132 {
133 type Output = [<$quantity Array>]<N>;
134
135 fn mul(self, rhs: f64) -> Self::Output {
136 let mut result = self.clone();
137 for val in result.values.as_mut_slice()
138 {
139 *val *= rhs;
140 }
141 result
142 }
143 }
144 impl<const N: usize> DivAssign<f64> for [<$quantity Array>]<N>
145 {
146
147 fn div_assign(&mut self, rhs: f64) {
148 for val in self.values.as_mut_slice()
149 {
150 *val /= rhs;
151 }
152 }
153 }
154 impl<const N: usize> Add<[<$quantity Array>]<N>> for [<$quantity Array>]<N>
155 {
156 type Output=Self;
157
158 fn add(self, rhs: [<$quantity Array>]<N>) -> Self {
159 let mut result = self;
160 result += rhs;
161 result
162 }
163 }
164 impl<const N: usize> Sub<[<$quantity Array>]<N>> for [<$quantity Array>]<N>
165 {
166 type Output=Self;
167 fn sub(self, rhs: [<$quantity Array>]<N>) -> Self {
168 let mut result = self;
169 result -= rhs;
170 result
171 }
172 }
173 impl<const N: usize> MulAssign<f64> for [<$quantity Array>]<N>
174 {
175
176 fn mul_assign(&mut self, rhs: f64) {
177 for val in self.values.as_mut_slice()
178 {
179 *val *= rhs;
180 }
181 }
182 }
183 impl<const N: usize> AddAssign<[<$quantity Array>]<N>> for [<$quantity Array>]<N>
184 {
185
186 fn add_assign(&mut self, rhs: [<$quantity Array>]<N>) {
187 if rhs.values.len() != self.values.len()
188 {
189 panic!("Slice dimensions do not match: {} != {}", rhs.values.len(), self.values.len());
190 }
191 let factor = rhs.unit.definition().convert_unchecked(self.unit.definition());
192 for (val, &rhs) in self.values.as_mut_slice().iter_mut().zip(rhs.values.as_slice())
193 {
194 *val += rhs*factor;
195 }
196 }
197 }
198 impl<const N: usize> SubAssign<[<$quantity Array>]<N>> for [<$quantity Array>]<N>
199 {
200
201 fn sub_assign(&mut self, rhs: [<$quantity Array>]<N>) {
202 if rhs.values.len() != self.values.len()
203 {
204 panic!("Slice dimensions do not match: {} != {}", rhs.values.len(), self.values.len());
205 }
206 let factor = rhs.unit.convert_unchecked(self.unit);
207 for (val, &rhs) in self.values.as_mut_slice().iter_mut().zip(rhs.values.as_slice())
208 {
209 *val -= rhs*factor;
210 }
211 }
212 }
213 }
214 }
215}
216
217#[macro_export]
218macro_rules! create_multivalue_quantities {
219 ($quantity:ident) =>
220 {
221 #[cfg(feature="serde")]
222 use serde_with::serde_as;
223 use std::ops::{Deref, DerefMut};
224 paste::paste!
225 {
226 #[cfg_attr(feature="serde", cfg_eval::cfg_eval, serde_as)]
227 #[derive(Copy, Clone, Debug, PartialEq)]
228 #[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
229 #[cfg_attr(feature="utoipa", derive(ToSchema))]
230 #[doc = "Array storage for a series of values and [`" [<$quantity Unit>]"`]."]
231 pub struct [<$quantity Array>]<const N: usize>
232 {
233 pub(crate) unit: [<$quantity Unit>],
234 #[cfg_attr(feature="serde", serde_as(as = "[_; N]"))]
235 pub(crate) values: [f64; N],
236 }
237
238 impl<const N: usize> Default for [<$quantity Array>]<N>
239 {
240 fn default() -> Self {
241 [<$quantity Array>]{unit: [<$quantity Unit>]::default(), values: [0.0; N]}
242 }
243 }
244
245 impl<const N: usize> Deref for [<$quantity Array>]<N>
246 {
247 type Target = [f64; N];
248 fn deref(&self) -> &[f64; N] {
249 &self.values
250 }
251 }
252
253 impl<const N: usize> DerefMut for [<$quantity Array>]<N>
254 {
255 fn deref_mut(&mut self) -> &mut [f64; N] {
256 &mut self.values
257 }
258 }
259
260 #[derive(Default, Clone, Debug, PartialEq)]
261 #[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
262 #[cfg_attr(feature="utoipa", derive(ToSchema))]
263 #[doc = "Vector storage for a series of values and [`" [<$quantity Unit>]"`]."]
264 pub struct [<$quantity Vec>]
265 {
266 pub(crate) unit: [<$quantity Unit>],
267 pub(crate) values: Vec<f64>
268 }
269
270 impl Deref for [<$quantity Vec>]
271 {
272 type Target = Vec<f64>;
273 fn deref(&self) -> &Vec<f64> {
274 &self.values
275 }
276 }
277 impl DerefMut for [<$quantity Vec>]
278 {
279 fn deref_mut(&mut self) -> &mut Vec<f64> {
280 &mut self.values
281 }
282 }
283
284 impl $crate::traits::FixedSliceQuantity<[<$quantity Unit>], f64> for [<$quantity Vec>]
285 {
286 fn unit(&self) -> [<$quantity Unit>] {
287 self.unit
288 }
289
290 fn values(&self) -> &[f64] {
291 &self.values.as_slice()
292 }
293
294 fn values_mut(&mut self) -> &mut [f64] {
295 self.values.as_mut_slice()
296 }
297
298 fn len(&self) -> usize {
299 self.values.len()
300 }
301
302 fn convert(&self, unit: [<$quantity Unit>]) -> Self
303 {
304 let mut result = self.clone();
305 result.convert_mut(unit);
306 return result;
307 }
308
309 #[inline]
310 fn convert_mut(&mut self, unit: [<$quantity Unit>]) {
311 let factor = self.unit.definition().convert_unchecked(unit.definition());
312 for val in self.values.as_mut_slice().iter_mut()
313 {
314 *val *= factor;
315 }
316 self.unit = unit;
317 }
318
319 #[inline]
320 fn try_convert(&self, unit: $crate::Units) -> Result<Self, RuntimeUnitError> where Self: Sized
321 {
322 let destination_unit: [<$quantity Unit>] = unit.try_into()?;
323 Ok(self.convert(destination_unit))
324 }
325 }
326 impl<const N: usize> $crate::traits::FixedSliceQuantity<[<$quantity Unit>], f64> for [<$quantity Array>]<N>
327 {
328 fn unit(&self) -> [<$quantity Unit>] {
329 self.unit
330 }
331
332 fn values(&self) -> &[f64] {
333 &self.values.as_slice()
334 }
335
336 fn values_mut(&mut self) -> &mut [f64] {
337 self.values.as_mut_slice()
338 }
339
340 fn len(&self) -> usize {
341 self.values.len()
342 }
343
344 fn convert(&self, unit: [<$quantity Unit>]) -> Self
345 {
346 let mut result = self.clone();
347 result.convert_mut(unit);
348 return result;
349 }
350
351 #[inline]
352 fn convert_mut(&mut self, unit: [<$quantity Unit>]) {
353 let factor = self.unit.definition().convert_unchecked(unit.definition());
354 for val in self.values.as_mut_slice().iter_mut()
355 {
356 *val *= factor;
357 }
358 self.unit = unit;
359 }
360
361 #[inline]
362 fn try_convert(&self, unit: $crate::Units) -> Result<Self, RuntimeUnitError> where Self: Sized
363 {
364 let destination_unit: [<$quantity Unit>] = unit.try_into()?;
365 Ok(self.convert(destination_unit))
366 }
367 }
368
369 }
370 }
371}
372
373#[macro_export]
374macro_rules! create_multivalue_quantities_vec_enum {
375 ($($quantity:ident),+) =>
376 {
377 paste::paste!{
378 #[derive(Clone, Debug, PartialEq)]
379 #[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
380 #[cfg_attr(feature="utoipa", derive(ToSchema))]
381 pub enum QuantitiesVec
386 {
387 $(
388 #[cfg(any(feature = "" $quantity, feature="All"))]
389 #[cfg_attr(feature="utoipa", schema(title = "" $quantity))]
390 $quantity([<$quantity Vec>]),
391 )+
392 }
393 impl QuantitiesVec
394 {
395 pub fn unit(&self) -> Units
397 {
398 use $crate::traits::FixedSliceQuantity;
399 match self
400 {
401 $(
402 #[cfg(any(feature = "" $quantity, feature="All"))]
403 QuantitiesVec::$quantity(x)=> $crate::Units::from(x.unit()),
404 )+
405 }
406 }
407 pub fn try_convert(&self, unit: Units) -> Result<QuantitiesVec, RuntimeUnitError>
409 {
410 use $crate::traits::FixedSliceQuantity;
411 match self
412 {
413 $(
414 #[cfg(any(feature = "" $quantity, feature="All"))]
415 QuantitiesVec::$quantity(x)=> {
416 Ok(QuantitiesVec::$quantity(x.try_convert(unit)?))
417 },
418 )+
419 }
420 }
421
422 pub fn new(value: Vec<f64>, unit: Units) -> QuantitiesVec
424 {
425 match unit
426 {
427 $(
428 #[cfg(any(feature = "" $quantity, feature="All"))]
429 Units::$quantity(x)=> {
430 QuantitiesVec::$quantity([<$quantity Vec>]::new(value, x))
431 },
432 )+
433 }
434 }
435 pub fn values(&self) -> Vec<f64>
437 {
438 use $crate::vector_quantity::VecQuantity;
439 VecQuantity::from(self.clone()).values
440 }
441 }
442 impl From<Units> for QuantitiesVec
444 {
445
446 fn from(value: Units) -> Self
447 {
448
449 match value
450 {
451 $(
452
453 #[cfg(any(feature = "" $quantity, feature="All"))]
454 Units::$quantity(x)=>
455 {
456 QuantitiesVec::new(vec![0.0], x.into())
457 },
458 )+
459 }
460
461 }
462 }
463 impl From<QuantitiesVec> for crate::vector_quantity::VecQuantity
464 {
465 fn from(value: QuantitiesVec) -> Self {
466 match value
467 {
468 $(
469 #[cfg(any(feature = "" $quantity, feature="All"))]
470 QuantitiesVec::$quantity(x)=>crate::vector_quantity::VecQuantity { values: x.values, unit: UnitDefinition{multiplier: x.unit.multiplier(), base: *[<$quantity:snake>]::[<$quantity:upper _UNIT_BASE>]} },
471 )+
472 }
473 }
474 }
475 impl ToString for QuantitiesVec
476 {
477 fn to_string(&self) -> String
478 {
479 match self
480 {
481 $(
482 #[cfg(any(feature = "" $quantity, feature="All"))]
483 QuantitiesVec::$quantity(x) => format!("{:?} {}", x.values, x.unit.abbreviation()),
484 )+
485 }
486 }
487 }
488 }
489 }
490}
491
492#[macro_export]
493macro_rules! create_multivalue_quantities_array_enum {
494 ($($quantity:ident),+) =>
495 {
496 paste::paste!{
497 #[derive(Copy, Clone, Debug, PartialEq)]
498 #[cfg_attr(feature="serde", derive(serde::Serialize, serde::Deserialize))]
499 pub enum QuantitiesArray<const N: usize>
504 {
505 $(
506 #[cfg(any(feature = "" $quantity, feature="All"))]
507 $quantity([<$quantity Array>]<N>),
508 )+
509 }
510 impl<const N: usize> QuantitiesArray<N>
511 {
512 pub fn unit(&self) -> Units
514 {
515 match self
516 {
517 $(
518 #[cfg(any(feature = "" $quantity, feature="All"))]
519 QuantitiesArray::$quantity(x)=> $crate::Units::from(x.unit),
520 )+
521 }
522 }
523 pub fn try_convert(&self, unit: Units) -> Result<QuantitiesArray<N>, RuntimeUnitError>
525 {
526 use $crate::traits::FixedSliceQuantity;
527 match self
528 {
529 $(
530 #[cfg(any(feature = "" $quantity, feature="All"))]
531 QuantitiesArray::$quantity(x)=> {
532 Ok(QuantitiesArray::$quantity(x.try_convert(unit)?))
533 },
534 )+
535 }
536 }
537
538 pub fn new(value: [f64; N], unit: Units) -> QuantitiesArray<N>
540 {
541 match unit
542 {
543 $(
544 #[cfg(any(feature = "" $quantity, feature="All"))]
545 Units::$quantity(x)=> {
546 QuantitiesArray::$quantity([<$quantity Array>]{values: value, unit:x})
547 },
548 )+
549 }
550 }
551 pub fn values(&self) -> [f64; N]
553 {
554 use $crate::array_quantity::ArrayQuantity;
555 ArrayQuantity::from(*self).values
556 }
557 }
558 impl<const N: usize> From<Units> for QuantitiesArray<N>
560 {
561 fn from(value: Units) -> Self
562 {
563 match value
564 {
565 $(
566 #[cfg(any(feature = "" $quantity, feature="All"))]
567 Units::$quantity(x)=> QuantitiesArray::new([0.0; N], x.into()),
568 )+
569 }
570
571 }
572 }
573 impl<const N: usize> From<QuantitiesArray<N>> for $crate::array_quantity::ArrayQuantity<N>
574 {
575 fn from(value: QuantitiesArray<N>) -> Self {
576 use crate::array_quantity::ArrayQuantity;
577 match value
578 {
579 $(
580 #[cfg(any(feature = "" $quantity, feature="All"))]
581 QuantitiesArray::$quantity(x)=>ArrayQuantity { values: x.values, unit: UnitDefinition{multiplier: x.unit.multiplier(), base: *[<$quantity:snake>]::[<$quantity:upper _UNIT_BASE>]} },
582 )+
583 }
584 }
585 }
586 impl<const N: usize> ToString for QuantitiesArray<N>
587 {
588 fn to_string(&self) -> String
589 {
590 match self
591 {
592 $(
593 #[cfg(any(feature = "" $quantity, feature="All"))]
594 QuantitiesArray::$quantity(x) => format!("{:?} {}", x.values, x.unit.abbreviation()),
595 )+
596 }
597 }
598 }
599 }
600 }
601}