1use core::fmt;
2
3#[derive(Debug, Clone, Copy)]
12pub struct DisplayWithUnit {
13 pub(crate) value: f64,
14 pub(crate) symbol: &'static str,
15}
16
17impl fmt::Display for DisplayWithUnit {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 fmt::Display::fmt(&self.value, f)?;
20 write!(f, " {}", self.symbol)
21 }
22}
23
24macro_rules! impl_common_ops {
25 ($t:ty) => {
26 impl core::ops::Add for $t {
27 type Output = Self;
28 fn add(self, rhs: Self) -> Self {
29 Self(self.0 + rhs.0)
30 }
31 }
32
33 impl core::ops::Sub for $t {
34 type Output = Self;
35 fn sub(self, rhs: Self) -> Self {
36 Self(self.0 - rhs.0)
37 }
38 }
39
40 impl core::ops::Neg for $t {
41 type Output = Self;
42 fn neg(self) -> Self {
43 Self(-self.0)
44 }
45 }
46
47 impl core::ops::Mul<f64> for $t {
48 type Output = Self;
49 fn mul(self, rhs: f64) -> Self {
50 Self(self.0 * rhs)
51 }
52 }
53
54 impl core::ops::Mul<$t> for f64 {
55 type Output = $t;
56 #[allow(clippy::suspicious_arithmetic_impl)]
57 fn mul(self, rhs: $t) -> $t {
58 rhs * self
60 }
61 }
62
63 impl core::ops::Div<f64> for $t {
64 type Output = Self;
65 fn div(self, rhs: f64) -> Self {
66 Self(self.0 / rhs)
67 }
68 }
69
70 impl core::ops::Div for $t {
71 type Output = f64;
72 fn div(self, rhs: Self) -> f64 {
73 self.0 / rhs.0
74 }
75 }
76
77 impl core::ops::AddAssign for $t {
78 fn add_assign(&mut self, rhs: Self) {
79 self.0 += rhs.0;
80 }
81 }
82
83 impl core::ops::SubAssign for $t {
84 fn sub_assign(&mut self, rhs: Self) {
85 self.0 -= rhs.0;
86 }
87 }
88
89 impl core::ops::MulAssign<f64> for $t {
90 fn mul_assign(&mut self, rhs: f64) {
91 self.0 *= rhs;
92 }
93 }
94
95 impl core::ops::DivAssign<f64> for $t {
96 fn div_assign(&mut self, rhs: f64) {
97 self.0 /= rhs;
98 }
99 }
100
101 impl core::iter::Sum for $t {
102 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
103 Self(iter.map(|v| v.0).sum::<f64>())
104 }
105 }
106 };
107}
108
109macro_rules! impl_quantity_display {
110 ($t:ty, $symbol:expr) => {
111 impl core::fmt::Display for $t {
112 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113 core::fmt::Display::fmt(&self.0, f)?;
114 f.write_str(concat!(" ", $symbol))
115 }
116 }
117 };
118}
119
120mod angular;
122mod electromagnetic;
123mod energy;
124mod geometry;
125mod mechanics;
126mod orbital;
127mod propulsion;
128mod radiation;
129mod thermal;
130mod waves;
131
132pub use angular::*;
134pub use electromagnetic::*;
135pub use energy::*;
136pub use geometry::*;
137pub use mechanics::*;
138pub use orbital::*;
139pub use propulsion::*;
140pub use radiation::*;
141pub use thermal::*;
142pub use waves::*;
143
144use core::ops::{Div, Mul};
149
150impl Div<Time> for Length {
154 type Output = Velocity;
155 fn div(self, rhs: Time) -> Velocity {
156 Velocity(self.0 / rhs.0)
157 }
158}
159
160impl Div<Velocity> for Length {
162 type Output = Time;
163 fn div(self, rhs: Velocity) -> Time {
164 Time(self.0 / rhs.0)
165 }
166}
167
168impl Mul<Time> for Velocity {
170 type Output = Length;
171 fn mul(self, rhs: Time) -> Length {
172 Length(self.0 * rhs.0)
173 }
174}
175
176impl Mul<Velocity> for Time {
177 type Output = Length;
178 fn mul(self, rhs: Velocity) -> Length {
179 Length(self.0 * rhs.0)
180 }
181}
182
183impl Mul<Time> for Acceleration {
185 type Output = Velocity;
186 fn mul(self, rhs: Time) -> Velocity {
187 Velocity(self.0 * rhs.0)
188 }
189}
190
191impl Mul<Acceleration> for Time {
192 type Output = Velocity;
193 fn mul(self, rhs: Acceleration) -> Velocity {
194 Velocity(self.0 * rhs.0)
195 }
196}
197
198impl Div<Time> for Velocity {
200 type Output = Acceleration;
201 fn div(self, rhs: Time) -> Acceleration {
202 Acceleration(self.0 / rhs.0)
203 }
204}
205
206impl Mul<Acceleration> for Mass {
208 type Output = Force;
209 fn mul(self, rhs: Acceleration) -> Force {
210 Force(self.0 * rhs.0)
211 }
212}
213
214impl Mul<Mass> for Acceleration {
215 type Output = Force;
216 fn mul(self, rhs: Mass) -> Force {
217 Force(self.0 * rhs.0)
218 }
219}
220
221impl Div<Mass> for Force {
223 type Output = Acceleration;
224 fn div(self, rhs: Mass) -> Acceleration {
225 Acceleration(self.0 / rhs.0)
226 }
227}
228
229impl Div<Acceleration> for Force {
231 type Output = Mass;
232 fn div(self, rhs: Acceleration) -> Mass {
233 Mass(self.0 / rhs.0)
234 }
235}
236
237impl Mul<Time> for Force {
239 type Output = Impulse;
240 fn mul(self, rhs: Time) -> Impulse {
241 Impulse(self.0 * rhs.0)
242 }
243}
244
245impl Mul<Force> for Time {
246 type Output = Impulse;
247 fn mul(self, rhs: Force) -> Impulse {
248 Impulse(self.0 * rhs.0)
249 }
250}
251
252impl Mul<Velocity> for Mass {
254 type Output = Momentum;
255 fn mul(self, rhs: Velocity) -> Momentum {
256 Momentum(self.0 * rhs.0)
257 }
258}
259
260impl Mul<Mass> for Velocity {
261 type Output = Momentum;
262 fn mul(self, rhs: Mass) -> Momentum {
263 Momentum(self.0 * rhs.0)
264 }
265}
266
267impl Div<Mass> for Impulse {
269 type Output = Velocity;
270 fn div(self, rhs: Mass) -> Velocity {
271 Velocity(self.0 / rhs.0)
272 }
273}
274
275impl Div<Mass> for Momentum {
277 type Output = Velocity;
278 fn div(self, rhs: Mass) -> Velocity {
279 Velocity(self.0 / rhs.0)
280 }
281}
282
283impl Div<Velocity> for Momentum {
285 type Output = Mass;
286 fn div(self, rhs: Velocity) -> Mass {
287 Mass(self.0 / rhs.0)
288 }
289}
290
291impl Mul<Self> for Length {
294 type Output = Area;
295 fn mul(self, rhs: Self) -> Area {
296 Area(self.0 * rhs.0)
297 }
298}
299
300impl Div<Length> for Area {
301 type Output = Length;
302 fn div(self, rhs: Length) -> Length {
303 Length(self.0 / rhs.0)
304 }
305}
306
307impl Mul<Length> for Area {
308 type Output = Volume;
309 fn mul(self, rhs: Length) -> Volume {
310 Volume(self.0 * rhs.0)
311 }
312}
313
314impl Mul<Area> for Length {
315 type Output = Volume;
316 fn mul(self, rhs: Area) -> Volume {
317 Volume(self.0 * rhs.0)
318 }
319}
320
321impl Div<Length> for Volume {
322 type Output = Area;
323 fn div(self, rhs: Length) -> Area {
324 Area(self.0 / rhs.0)
325 }
326}
327
328impl Div<Area> for Volume {
329 type Output = Length;
330 fn div(self, rhs: Area) -> Length {
331 Length(self.0 / rhs.0)
332 }
333}
334
335impl Div<Volume> for Mass {
338 type Output = Density;
339 fn div(self, rhs: Volume) -> Density {
340 Density(self.0 / rhs.0)
341 }
342}
343
344impl Mul<Volume> for Density {
345 type Output = Mass;
346 fn mul(self, rhs: Volume) -> Mass {
347 Mass(self.0 * rhs.0)
348 }
349}
350
351impl Mul<Density> for Volume {
352 type Output = Mass;
353 fn mul(self, rhs: Density) -> Mass {
354 Mass(self.0 * rhs.0)
355 }
356}
357
358impl Div<Area> for Force {
359 type Output = Pressure;
360 fn div(self, rhs: Area) -> Pressure {
361 Pressure(self.0 / rhs.0)
362 }
363}
364
365impl Mul<Area> for Pressure {
366 type Output = Force;
367 fn mul(self, rhs: Area) -> Force {
368 Force(self.0 * rhs.0)
369 }
370}
371
372impl Mul<Pressure> for Area {
373 type Output = Force;
374 fn mul(self, rhs: Pressure) -> Force {
375 Force(self.0 * rhs.0)
376 }
377}
378
379impl Mul<Length> for Force {
382 type Output = Energy;
383 fn mul(self, rhs: Length) -> Energy {
384 Energy(self.0 * rhs.0)
385 }
386}
387
388impl Mul<Force> for Length {
389 type Output = Energy;
390 fn mul(self, rhs: Force) -> Energy {
391 Energy(self.0 * rhs.0)
392 }
393}
394
395impl Div<Time> for Energy {
396 type Output = Power;
397 fn div(self, rhs: Time) -> Power {
398 Power(self.0 / rhs.0)
399 }
400}
401
402impl Mul<Time> for Power {
403 type Output = Energy;
404 fn mul(self, rhs: Time) -> Energy {
405 Energy(self.0 * rhs.0)
406 }
407}
408
409impl Div<Length> for Energy {
410 type Output = Force;
411 fn div(self, rhs: Length) -> Force {
412 Force(self.0 / rhs.0)
413 }
414}
415
416impl Div<Mass> for Energy {
417 type Output = SpecificEnergy;
418 fn div(self, rhs: Mass) -> SpecificEnergy {
419 SpecificEnergy(self.0 / rhs.0)
420 }
421}
422
423impl Div<Length> for GravitationalParameter {
426 type Output = SpecificEnergy;
427 fn div(self, rhs: Length) -> SpecificEnergy {
428 SpecificEnergy(self.0 / rhs.0)
429 }
430}
431
432impl Div<Area> for GravitationalParameter {
433 type Output = Acceleration;
434 fn div(self, rhs: Area) -> Acceleration {
435 Acceleration(self.0 / rhs.0)
436 }
437}
438
439impl Mul<Self> for Velocity {
440 type Output = SpecificEnergy;
441 fn mul(self, rhs: Self) -> SpecificEnergy {
442 SpecificEnergy(self.0 * rhs.0)
443 }
444}
445
446impl Mul<Velocity> for Length {
447 type Output = SpecificAngularMomentum;
448 fn mul(self, rhs: Velocity) -> SpecificAngularMomentum {
449 SpecificAngularMomentum(self.0 * rhs.0)
450 }
451}
452
453impl Mul<Length> for Velocity {
454 type Output = SpecificAngularMomentum;
455 fn mul(self, rhs: Length) -> SpecificAngularMomentum {
456 SpecificAngularMomentum(self.0 * rhs.0)
457 }
458}
459
460impl Div<Time> for Area {
461 type Output = SpecificAngularMomentum;
462 fn div(self, rhs: Time) -> SpecificAngularMomentum {
463 SpecificAngularMomentum(self.0 / rhs.0)
464 }
465}
466
467impl Div<Time> for Angle {
470 type Output = AngularVelocity;
471 fn div(self, rhs: Time) -> AngularVelocity {
472 AngularVelocity(self.0 / rhs.0)
473 }
474}
475
476impl Mul<Time> for AngularVelocity {
477 type Output = Angle;
478 fn mul(self, rhs: Time) -> Angle {
479 Angle(self.0 * rhs.0)
480 }
481}
482
483impl Mul<AngularVelocity> for Time {
484 type Output = Angle;
485 fn mul(self, rhs: AngularVelocity) -> Angle {
486 Angle(self.0 * rhs.0)
487 }
488}
489
490impl Div<Time> for AngularVelocity {
491 type Output = AngularAcceleration;
492 fn div(self, rhs: Time) -> AngularAcceleration {
493 AngularAcceleration(self.0 / rhs.0)
494 }
495}
496
497impl Mul<AngularAcceleration> for MomentOfInertia {
498 type Output = Torque;
499 fn mul(self, rhs: AngularAcceleration) -> Torque {
500 Torque(self.0 * rhs.0)
501 }
502}
503
504impl Mul<MomentOfInertia> for AngularAcceleration {
505 type Output = Torque;
506 fn mul(self, rhs: MomentOfInertia) -> Torque {
507 Torque(self.0 * rhs.0)
508 }
509}
510
511impl Div<AngularAcceleration> for Torque {
512 type Output = MomentOfInertia;
513 fn div(self, rhs: AngularAcceleration) -> MomentOfInertia {
514 MomentOfInertia(self.0 / rhs.0)
515 }
516}
517
518impl Mul<Time> for Torque {
519 type Output = AngularMomentum;
520 fn mul(self, rhs: Time) -> AngularMomentum {
521 AngularMomentum(self.0 * rhs.0)
522 }
523}
524
525impl Div<Time> for AngularMomentum {
526 type Output = Torque;
527 fn div(self, rhs: Time) -> Torque {
528 Torque(self.0 / rhs.0)
529 }
530}
531
532impl Div<Time> for Mass {
536 type Output = MassFlowRate;
537 fn div(self, rhs: Time) -> MassFlowRate {
538 MassFlowRate(self.0 / rhs.0)
539 }
540}
541
542impl Mul<Time> for MassFlowRate {
544 type Output = Mass;
545 fn mul(self, rhs: Time) -> Mass {
546 Mass(self.0 * rhs.0)
547 }
548}
549
550impl Mul<MassFlowRate> for Time {
551 type Output = Mass;
552 fn mul(self, rhs: MassFlowRate) -> Mass {
553 Mass(self.0 * rhs.0)
554 }
555}
556
557impl Mul<Velocity> for MassFlowRate {
559 type Output = Force;
560 fn mul(self, rhs: Velocity) -> Force {
561 Force(self.0 * rhs.0)
562 }
563}
564
565impl Mul<MassFlowRate> for Velocity {
566 type Output = Force;
567 fn mul(self, rhs: MassFlowRate) -> Force {
568 Force(self.0 * rhs.0)
569 }
570}
571
572impl Div<MassFlowRate> for Force {
574 type Output = Velocity;
575 fn div(self, rhs: MassFlowRate) -> Velocity {
576 Velocity(self.0 / rhs.0)
577 }
578}
579
580impl Div<Velocity> for Force {
582 type Output = MassFlowRate;
583 fn div(self, rhs: Velocity) -> MassFlowRate {
584 MassFlowRate(self.0 / rhs.0)
585 }
586}
587
588impl Div<Time> for ElectricCharge {
592 type Output = ElectricCurrent;
593 fn div(self, rhs: Time) -> ElectricCurrent {
594 ElectricCurrent(self.0 / rhs.0)
595 }
596}
597
598impl Mul<Time> for ElectricCurrent {
600 type Output = ElectricCharge;
601 fn mul(self, rhs: Time) -> ElectricCharge {
602 ElectricCharge(self.0 * rhs.0)
603 }
604}
605
606impl Mul<ElectricCurrent> for Time {
607 type Output = ElectricCharge;
608 fn mul(self, rhs: ElectricCurrent) -> ElectricCharge {
609 ElectricCharge(self.0 * rhs.0)
610 }
611}
612
613impl Div<ElectricCurrent> for Power {
615 type Output = Voltage;
616 fn div(self, rhs: ElectricCurrent) -> Voltage {
617 Voltage(self.0 / rhs.0)
618 }
619}
620
621impl Mul<ElectricCurrent> for Voltage {
623 type Output = Power;
624 fn mul(self, rhs: ElectricCurrent) -> Power {
625 Power(self.0 * rhs.0)
626 }
627}
628
629impl Mul<Voltage> for ElectricCurrent {
630 type Output = Power;
631 fn mul(self, rhs: Voltage) -> Power {
632 Power(self.0 * rhs.0)
633 }
634}
635
636impl Div<ElectricCharge> for Energy {
638 type Output = Voltage;
639 fn div(self, rhs: ElectricCharge) -> Voltage {
640 Voltage(self.0 / rhs.0)
641 }
642}
643
644impl Mul<ElectricCharge> for Voltage {
646 type Output = Energy;
647 fn mul(self, rhs: ElectricCharge) -> Energy {
648 Energy(self.0 * rhs.0)
649 }
650}
651
652impl Mul<Voltage> for ElectricCharge {
653 type Output = Energy;
654 fn mul(self, rhs: Voltage) -> Energy {
655 Energy(self.0 * rhs.0)
656 }
657}
658
659impl Div<ElectricCurrent> for Voltage {
661 type Output = Resistance;
662 fn div(self, rhs: ElectricCurrent) -> Resistance {
663 Resistance(self.0 / rhs.0)
664 }
665}
666
667impl Mul<Resistance> for ElectricCurrent {
669 type Output = Voltage;
670 fn mul(self, rhs: Resistance) -> Voltage {
671 Voltage(self.0 * rhs.0)
672 }
673}
674
675impl Mul<ElectricCurrent> for Resistance {
676 type Output = Voltage;
677 fn mul(self, rhs: ElectricCurrent) -> Voltage {
678 Voltage(self.0 * rhs.0)
679 }
680}
681
682impl Div<Voltage> for ElectricCharge {
684 type Output = Capacitance;
685 fn div(self, rhs: Voltage) -> Capacitance {
686 Capacitance(self.0 / rhs.0)
687 }
688}
689
690impl Mul<Voltage> for Capacitance {
692 type Output = ElectricCharge;
693 fn mul(self, rhs: Voltage) -> ElectricCharge {
694 ElectricCharge(self.0 * rhs.0)
695 }
696}
697
698impl Mul<Capacitance> for Voltage {
699 type Output = ElectricCharge;
700 fn mul(self, rhs: Capacitance) -> ElectricCharge {
701 ElectricCharge(self.0 * rhs.0)
702 }
703}
704
705impl Mul<Area> for MagneticFluxDensity {
707 type Output = MagneticFlux;
708 fn mul(self, rhs: Area) -> MagneticFlux {
709 MagneticFlux(self.0 * rhs.0)
710 }
711}
712
713impl Mul<MagneticFluxDensity> for Area {
714 type Output = MagneticFlux;
715 fn mul(self, rhs: MagneticFluxDensity) -> MagneticFlux {
716 MagneticFlux(self.0 * rhs.0)
717 }
718}
719
720impl Div<Area> for MagneticFlux {
722 type Output = MagneticFluxDensity;
723 fn div(self, rhs: Area) -> MagneticFluxDensity {
724 MagneticFluxDensity(self.0 / rhs.0)
725 }
726}
727
728impl Div<ElectricCurrent> for MagneticFlux {
730 type Output = Inductance;
731 fn div(self, rhs: ElectricCurrent) -> Inductance {
732 Inductance(self.0 / rhs.0)
733 }
734}
735
736impl Mul<ElectricCurrent> for Inductance {
738 type Output = MagneticFlux;
739 fn mul(self, rhs: ElectricCurrent) -> MagneticFlux {
740 MagneticFlux(self.0 * rhs.0)
741 }
742}
743
744impl Mul<Inductance> for ElectricCurrent {
745 type Output = MagneticFlux;
746 fn mul(self, rhs: Inductance) -> MagneticFlux {
747 MagneticFlux(self.0 * rhs.0)
748 }
749}
750
751impl Div<Area> for Power {
755 type Output = HeatFlux;
756 fn div(self, rhs: Area) -> HeatFlux {
757 HeatFlux(self.0 / rhs.0)
758 }
759}
760
761impl Mul<Area> for HeatFlux {
763 type Output = Power;
764 fn mul(self, rhs: Area) -> Power {
765 Power(self.0 * rhs.0)
766 }
767}
768
769impl Mul<HeatFlux> for Area {
770 type Output = Power;
771 fn mul(self, rhs: HeatFlux) -> Power {
772 Power(self.0 * rhs.0)
773 }
774}