1use std::any::Any;
42use std::fmt::{Display, Formatter};
43use std::ops::Div;
44
45mod acceleration;
46mod angular;
47mod angular_acceleration;
48mod angular_momentum;
49mod angular_velocity;
50mod area;
51mod coef;
52mod distance;
53mod electric_capacitance;
54mod electric_charge;
55mod electric_conductance;
56mod electric_current;
57mod electric_potential;
58mod electric_resistance;
59mod energy;
60mod force;
61pub mod heat_capacity;
62pub mod heat_flux;
63pub mod inertia;
64mod magnetic_angular_velocity;
65mod magnetic_induction;
66mod magnetic_moment;
67pub mod mass;
68mod momentum;
69mod power;
70mod temperature;
71mod temperature_difference;
72pub mod thermal_conductance;
73mod thermal_conductivity;
74mod torque;
75pub mod vector;
76mod velocity;
77mod volume;
78
79pub trait VectorQuantity: PhysicalQuantity {}
81
82pub trait PhysicalQuantity: Any {
83 fn as_any(&self) -> &dyn Any;
84
85 fn is_zero(&self) -> bool;
86
87 fn default_unit_value(&self) -> f64;
88
89 fn set_value(&mut self, value: f64);
90
91 fn unit_display_name(&self) -> String;
93}
94
95#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96pub enum DistanceType {
97 M,
98 KM,
99 LightYear,
100}
101#[derive(Clone, Copy, Debug, PartialEq)]
102pub enum VelocityType {
103 MPerSecond,
104 KmPerHour,
105 KmPerSecond,
106 LightSpeed,
107}
108#[derive(Clone, Debug, PartialEq, Copy)]
120pub struct Distance {
121 default_type: DistanceType,
122 v: f64,
123}
124
125#[derive(Clone, Debug, PartialEq, Copy)]
137pub struct Velocity {
138 default_type: VelocityType,
139 v: f64,
140}
141
142
143#[derive(Clone, Debug, PartialEq, Copy)]
155pub struct Acceleration {
156 default_type: AccelerationType,
157 v: f64,
158}
159
160#[derive(Clone, Debug, PartialEq, Copy)]
161pub enum AccelerationType {
162 MPerSecond2,
163 KmPerHour2,
164 G,
165}
166
167#[derive(Clone, Debug, PartialEq, Copy)]
168pub enum AngularType {
169 Rad,
170 Deg,
171}
172
173#[derive(Clone, Debug, PartialEq, Copy)]
185pub struct Angular {
186 default_type: AngularType,
187 v: f64,
188}
189
190#[derive(Clone, Debug, PartialEq, Copy, Default)]
191pub enum AngularVelocityType {
192 #[default]
193 RadperSecond,
194 DegPerSecond,
195 RadperHour,
196 DegperHour,
197}
198
199#[derive(Clone, Debug, PartialEq, Copy)]
211pub struct AngularVelocity {
212 default_type: AngularVelocityType,
213 v: f64,
214}
215
216
217#[derive(Clone, Debug, PartialEq, Copy)]
218pub enum AngularAccelerationType {
219 RadperSecond2,
220 DegPerSecond2,
221}
222
223#[derive(Clone, Debug, PartialEq, Copy)]
235pub struct AngularAcceleration {
236 default_type: AngularAccelerationType,
237 v: f64,
238}
239
240#[derive(Clone, Debug, PartialEq, PartialOrd, Copy)]
252pub struct Coef {
253 v: f64,
254}
255
256#[derive(Clone, Debug, PartialEq, Copy)]
257pub enum MassType {
258 Kg,
259 g,
260}
261
262#[derive(Clone, Debug, PartialEq, Copy)]
274pub struct Mass {
275 default_type: MassType,
276 pub v: f64,
277}
278
279#[derive(Clone, Debug, PartialEq, Copy)]
280pub enum InertiaType {
281 KgM2,
283 KgMm2,
285}
286
287#[derive(Clone, Debug, PartialEq, Copy)]
311pub struct Inertia {
312 default_type: InertiaType,
313 pub v: f64,
314}
315
316#[derive(Clone, Debug, PartialEq, Copy)]
317pub enum AngularMomentumType {
318 KgM2perSecond, KgKm2perSecond, Nms, MillNms, MicroNms, NanoNms, }
325#[derive(Clone, Debug, PartialEq, Copy)]
337pub struct AngularMomentum {
338 default_type: AngularMomentumType,
339 pub v: f64,
340}
341
342#[derive(Clone, Debug, PartialEq, Copy)]
343pub enum MomentumType {
344 KgMperSecond, KgKmperSecond, }
347#[derive(Clone, Debug, PartialEq, Copy)]
359pub struct Momentum {
360 default_type: MomentumType,
361 pub v: f64,
362}
363
364
365#[derive(Clone, Debug, PartialEq, Copy)]
384pub struct Vector3<T: VectorQuantity + Default> {
385 pub x: T,
386 pub y: T,
387 pub z: T,
388}
389
390impl<T: VectorQuantity + Default + Display> Display for Vector3<T> {
391 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
392 write!(f, "({}, {}, {})", self.x, self.y, self.z)
393 }
394}
395
396#[derive(Clone, Copy, Debug, PartialEq)]
397pub enum AreaType {
398 M2,
399 KM2,
400}
401
402#[derive(Clone, Copy, Debug, PartialEq)]
414pub struct Area {
415 default_type: AreaType,
416 pub v: f64,
417}
418
419#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
420pub enum MagneticInductionType {
421 Gauss,
422 #[default]
423 Tesla,
424 MillTesla, MicroTesla, NanoTesla, MillGauss, KiloGauss, }
430#[derive(Clone, Copy, Debug, PartialEq)]
442pub struct MagneticInduction {
443 default_type: MagneticInductionType,
444 pub v: f64,
445}
446
447
448#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
449pub enum MagneticMomentType {
450 AM2, MillAM2, MicroAM2, NanoAM2, JPerTesla, MillJPerTesla, MicroJPerTesla, NanoJPerTesla, }
459
460#[derive(Clone, Copy, Debug, PartialEq)]
472pub struct MagneticMoment {
473 default_type: MagneticMomentType,
474 pub v: f64,
475}
476
477
478#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
479pub enum TorqueType {
480 NM, MillNM, MicroNM, NanoNM, KNM, MNM, }
487
488#[derive(Clone, Copy, Debug, PartialEq)]
500pub struct Torque {
501 default_type: TorqueType,
502 pub v: f64,
503}
504
505
506#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
507pub enum EnergyType {
508 Joule, MillJoule, MicroJoule, NanoJoule, KiloJoule, MegaJoule, ElectronVolt, KiloElectronVolt, MegaElectronVolt, }
518
519#[derive(Clone, Copy, Debug, PartialEq)]
531pub struct Energy {
532 default_type: EnergyType,
533 pub v: f64,
534}
535
536
537#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
538pub enum ForceType {
539 Newton, MillNewton, MicroNewton, NanoNewton, KiloNewton, MegaNewton, }
546
547#[derive(Clone, Copy, Debug, PartialEq)]
559pub struct Force {
560 default_type: ForceType,
561 pub v: f64,
562}
563
564
565#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
566pub enum PowerType {
567 Watt, MillWatt, MicroWatt, NanoWatt, KiloWatt, MegaWatt, HorsePower, }
575
576#[derive(Clone, Copy, Debug, PartialEq)]
588pub struct Power {
589 default_type: PowerType,
590 pub v: f64,
591}
592
593
594#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
595pub enum MagneticAngularVelocityType {
596 TeslaRadPerSecond, MillTeslaRadPerSecond, MicroTeslaRadPerSecond, NanoTeslaRadPerSecond, GaussRadPerSecond, MillGaussRadPerSecond, KiloGaussRadPerSecond, }
604
605#[derive(Clone, Copy, Debug, PartialEq)]
617pub struct MagneticAngularVelocity {
618 default_type: MagneticAngularVelocityType,
619 pub v: f64,
620}
621
622
623#[derive(Clone, Debug, PartialEq, Copy)]
624pub enum VolumeType {
625 M3,
626 KM3,
627}
628#[derive(Clone, Copy, Debug, PartialEq)]
640pub struct Volume {
641 default_type: VolumeType,
642 pub v: f64,
643}
644
645#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
648pub enum ElectricCurrentType {
649 A,
650 MilliA,
651 MicroA,
652 KiloA,
653}
654
655#[derive(Clone, Copy, Debug, PartialEq)]
659pub struct ElectricCurrent {
660 default_type: ElectricCurrentType,
661 pub v: f64,
662}
663
664#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
665pub enum ElectricPotentialType {
666 V,
667 MilliV,
668 MicroV,
669 KiloV,
670}
671
672#[derive(Clone, Copy, Debug, PartialEq)]
676pub struct ElectricPotential {
677 default_type: ElectricPotentialType,
678 pub v: f64,
679}
680
681#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
682pub enum ElectricResistanceType {
683 Ohm,
684 MillOhm,
685 KiloOhm,
686 MegaOhm,
687}
688
689#[derive(Clone, Copy, Debug, PartialEq)]
693pub struct ElectricResistance {
694 default_type: ElectricResistanceType,
695 pub v: f64,
696}
697
698#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
699pub enum ElectricChargeType {
700 Coulomb,
701 MilliCoulomb,
702 MicroCoulomb,
703 NanoCoulomb,
704}
705
706#[derive(Clone, Copy, Debug, PartialEq)]
710pub struct ElectricCharge {
711 default_type: ElectricChargeType,
712 pub v: f64,
713}
714
715#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
716pub enum ElectricCapacitanceType {
717 Farad,
718 MilliFarad,
719 MicroFarad,
720 NanoFarad,
721 PicoFarad,
722}
723
724#[derive(Clone, Copy, Debug, PartialEq)]
728pub struct ElectricCapacitance {
729 default_type: ElectricCapacitanceType,
730 pub v: f64,
731}
732
733#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
734pub enum ElectricConductanceType {
735 Siemens,
736 MilliSiemens,
737 MicroSiemens,
738}
739
740#[derive(Clone, Copy, Debug, PartialEq)]
744pub struct ElectricConductance {
745 default_type: ElectricConductanceType,
746 pub v: f64,
747}
748
749#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
794pub struct Temperature {
795 kelvin: f64,
798}
799
800#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
827pub struct TemperatureDifference {
828 kelvin: f64,
830}
831
832#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
833pub enum HeatFluxType {
834 WattPerSquareMeter,
836 KiloWattPerSquareMeter,
838 MilliWattPerSquareCentiMeter,
841}
842
843#[derive(Clone, Copy, Debug, PartialEq)]
893pub struct HeatFlux {
894 default_type: HeatFluxType,
895 pub v: f64,
896}
897
898#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
899pub enum ThermalConductivityType {
900 WattPerMeterKelvin,
902 KiloWattPerMeterKelvin,
904 MilliWattPerCentiMeterKelvin,
908}
909
910#[derive(Clone, Copy, Debug, PartialEq)]
956pub struct ThermalConductivity {
957 default_type: ThermalConductivityType,
958 pub v: f64,
959}
960
961#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
962pub enum HeatCapacityType {
963 JoulePerKelvin,
965 KiloJoulePerKelvin,
967}
968
969#[derive(Clone, Copy, Debug, PartialEq)]
1011pub struct HeatCapacity {
1012 default_type: HeatCapacityType,
1013 pub v: f64,
1014}
1015
1016#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1017pub enum ThermalConductanceType {
1018 WattPerKelvin,
1020 MilliWattPerKelvin,
1022}
1023
1024#[derive(Clone, Copy, Debug, PartialEq)]
1059pub struct ThermalConductance {
1060 default_type: ThermalConductanceType,
1061 pub v: f64,
1062}
1063
1064
1065impl Default for Distance {
1066 fn default() -> Self {
1067 Distance::from_m(0.0)
1068 }
1069}
1070
1071impl PhysicalQuantity for Distance {
1072 fn as_any(&self) -> &dyn Any {
1073 self
1074}
1075 fn is_zero(&self) -> bool {
1076 self.v == 0.0
1077 }
1078
1079 fn default_unit_value(&self) -> f64 {
1080 self.as_m()
1081 }
1082
1083 fn set_value(&mut self, value: f64) {
1084 self.v = value;
1085 }
1086 fn unit_display_name(&self) -> String {
1087 "Distance (m)".to_string()
1088 }
1089}
1090
1091impl Default for Angular {
1092 fn default() -> Self {
1093 Angular::from_rad(0.0)
1094 }
1095}
1096
1097impl PhysicalQuantity for Angular {
1098 fn as_any(&self) -> &dyn Any {
1099 self
1100}
1101 fn is_zero(&self) -> bool {
1102 self.v == 0.0
1103 }
1104 fn default_unit_value(&self) -> f64 {
1105 self.as_rad()
1106 }
1107
1108 fn set_value(&mut self, value: f64) {
1109 self.v = value;
1110 }
1111 fn unit_display_name(&self) -> String {
1112 "Angular (rad)".to_string()
1113 }
1114}
1115
1116impl Default for AngularVelocity {
1117 fn default() -> Self {
1118 AngularVelocity::from_rad_per_second(0.0)
1119 }
1120}
1121
1122impl Div for AngularMomentum {
1123 type Output = Coef;
1124 fn div(self, rhs: Self) -> Self::Output {
1125 let v = self.default_unit_value() / rhs.default_unit_value();
1126 Coef::new(v)
1127 }
1128}
1129
1130impl Default for Coef {
1131 fn default() -> Self {
1132 Coef::new(1.0)
1133 }
1134}
1135
1136impl Default for AngularAcceleration {
1137 fn default() -> Self {
1138 AngularAcceleration::from_rad_per_second2(0.0)
1139 }
1140}
1141
1142impl<T: VectorQuantity + Default> Default for Vector3<T> {
1143 fn default() -> Self {
1144 Vector3 {
1145 x: T::default(),
1146 y: T::default(),
1147 z: T::default(),
1148 }
1149 }
1150}
1151
1152pub fn time_delta_from_secs_f64(secs: f64) -> chrono::TimeDelta {
1154 let nanos = (secs * 1_000_000_000.0) as i64;
1155 chrono::TimeDelta::nanoseconds(nanos)
1156}
1157
1158pub fn time_delta_to_secs_f64(td: &chrono::TimeDelta) -> f64 {
1160 td.num_seconds() as f64 + td.subsec_nanos() as f64 * 1e-9
1161}
1162
1163
1164macro_rules! impl_display_physics {
1168 ($type:ty) => {
1169 impl std::fmt::Display for $type {
1170 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1171 write!(f, "{}", self.default_unit_value())
1172 }
1173 }
1174 };
1175}
1176
1177impl_display_physics!(Distance);
1178impl_display_physics!(Velocity);
1179impl_display_physics!(Acceleration);
1180impl_display_physics!(Angular);
1181impl_display_physics!(AngularVelocity);
1182impl_display_physics!(AngularAcceleration);
1183impl_display_physics!(Coef);
1184impl_display_physics!(Mass);
1185impl_display_physics!(Momentum);
1186impl_display_physics!(AngularMomentum);
1187impl_display_physics!(Area);
1188impl_display_physics!(Volume);
1189impl_display_physics!(MagneticInduction);
1190impl_display_physics!(MagneticMoment);
1191impl_display_physics!(Torque);
1192impl_display_physics!(Energy);
1193impl_display_physics!(Force);
1194impl_display_physics!(Power);
1195impl_display_physics!(MagneticAngularVelocity);
1196impl_display_physics!(ElectricCurrent);
1197impl_display_physics!(ElectricPotential);
1198impl_display_physics!(ElectricResistance);
1199impl_display_physics!(ElectricCharge);
1200impl_display_physics!(ElectricCapacitance);
1201impl_display_physics!(ElectricConductance);
1202#[cfg(test)]
1203mod tests {
1204 use super::*;
1205 use approx::assert_relative_eq;
1206 #[test]
1207 fn test_as_any() {
1208 let g: &dyn PhysicalQuantity = &Acceleration::from_g(1.23);
1209 let _d = g.as_any().downcast_ref::<Acceleration>().unwrap();
1210
1211 let g: &dyn PhysicalQuantity = &Area::from_m2(10.0);
1212 let _d = g.as_any().downcast_ref::<Area>().unwrap();
1213
1214 let g: &dyn PhysicalQuantity = &Distance::from_m(10.0);
1215 let d = g.as_any().downcast_ref::<Distance>().unwrap();
1216 assert_eq!(d.default_type, DistanceType::M);
1217
1218 let g: &dyn PhysicalQuantity = &Velocity::from_m_per_sec(10.0);
1219 let d = g.as_any().downcast_ref::<Velocity>().unwrap();
1220 assert_eq!(d.default_type, VelocityType::MPerSecond);
1221
1222 let g: &dyn PhysicalQuantity = &Acceleration::from_g(1.23);
1223 let d = g.as_any().downcast_ref::<Acceleration>().unwrap();
1224 assert_eq!(d.default_type, AccelerationType::G);
1225
1226 let g: &dyn PhysicalQuantity = &Angular::from_rad(1.23);
1227 let d = g.as_any().downcast_ref::<Angular>().unwrap();
1228 assert_eq!(d.default_type, AngularType::Rad);
1229
1230 let g: &dyn PhysicalQuantity = &AngularVelocity::from_rad_per_hour(1.23);
1231 let d = g.as_any().downcast_ref::<AngularVelocity>().unwrap();
1232 assert_eq!(d.default_type, AngularVelocityType::RadperHour);
1233
1234 let g: &dyn PhysicalQuantity = &Coef::new(1.23);
1235 let d = g.as_any().downcast_ref::<Coef>().unwrap();
1236 assert_eq!(d.v, 1.23);
1237
1238 let g: &dyn PhysicalQuantity = &AngularAcceleration::from_rad_per_second2(1.23);
1239 let d = g.as_any().downcast_ref::<AngularAcceleration>().unwrap();
1240 assert_eq!(d.default_type, AngularAccelerationType::RadperSecond2);
1241 }
1242
1243 #[test]
1244 fn test_acceleration_default() {
1245 let a = Acceleration::default();
1246 assert_eq!(0.0, a.as_m_per_s2());
1247 }
1248
1249 #[test]
1250 fn test_angular_velocity_default() {
1251 let a = AngularVelocity::default();
1252 assert_eq!(0.0, a.as_rad_per_hour());
1253
1254 let a = AngularAcceleration::default();
1255 assert_eq!(0.0, a.as_rad_per_second2());
1256 }
1257
1258 #[test]
1259 fn test_angular_is_zero() {
1260 let a = Angular::from_rad(0.0);
1261 assert_eq!(true, a.is_zero());
1262 let a = Angular::from_rad(1.0);
1263 assert_eq!(false, a.is_zero());
1264 }
1265
1266 #[test]
1267 fn test_volume_clone() {
1268 let a = Volume::from_m3(3.8);
1269 let b = a.clone();
1270 assert_relative_eq!(a.as_km3(), b.as_km3(), epsilon = 1e-8);
1271 }
1272
1273 #[test]
1274 fn test_magnetic_moment_as_any() {
1275 let g: &dyn PhysicalQuantity = &MagneticMoment::from_am2(1.23);
1276 let d = g.as_any().downcast_ref::<MagneticMoment>().unwrap();
1277 assert_eq!(d.default_type, MagneticMomentType::AM2);
1278 }
1279
1280 #[test]
1281 fn test_magnetic_moment_default() {
1282 let mm = MagneticMoment::default();
1283 assert_eq!(0.0, mm.as_am2());
1284 }
1285
1286 #[test]
1287 fn test_magnetic_moment_is_zero() {
1288 let mm = MagneticMoment::from_am2(0.0);
1289 assert_eq!(true, mm.is_zero());
1290 let mm = MagneticMoment::from_am2(1.0);
1291 assert_eq!(false, mm.is_zero());
1292 }
1293
1294 #[test]
1295 fn test_torque_as_any() {
1296 let g: &dyn PhysicalQuantity = &Torque::from_nm(1.23);
1297 let d = g.as_any().downcast_ref::<Torque>().unwrap();
1298 assert_eq!(d.default_type, TorqueType::NM);
1299 }
1300
1301 #[test]
1302 fn test_torque_default() {
1303 let t = Torque::default();
1304 assert_eq!(0.0, t.as_nm());
1305 }
1306
1307 #[test]
1308 fn test_torque_is_zero() {
1309 let t = Torque::from_nm(0.0);
1310 assert_eq!(true, t.is_zero());
1311 let t = Torque::from_nm(1.0);
1312 assert_eq!(false, t.is_zero());
1313 }
1314
1315 #[test]
1316 fn test_energy_as_any() {
1317 let g: &dyn PhysicalQuantity = &Energy::from_joule(1.23);
1318 let d = g.as_any().downcast_ref::<Energy>().unwrap();
1319 assert_eq!(d.default_type, EnergyType::Joule);
1320 }
1321
1322 #[test]
1323 fn test_energy_default() {
1324 let e = Energy::default();
1325 assert_eq!(0.0, e.as_joule());
1326 }
1327
1328 #[test]
1329 fn test_energy_is_zero() {
1330 let e = Energy::from_joule(0.0);
1331 assert_eq!(true, e.is_zero());
1332 let e = Energy::from_joule(1.0);
1333 assert_eq!(false, e.is_zero());
1334 }
1335
1336 #[test]
1337 fn test_angular_default_unit_value_is_rad() {
1338 let a_rad = Angular::from_rad(std::f64::consts::PI);
1340 assert_relative_eq!(a_rad.default_unit_value(), a_rad.as_rad(), epsilon = 1e-12);
1341
1342 let a_deg = Angular::from_deg(180.0);
1344 assert_relative_eq!(a_deg.default_unit_value(), a_deg.as_rad(), epsilon = 1e-12);
1345
1346 let cases = vec![
1348 -720.0, -360.0, -45.5, 0.0, 12.34, 90.0, 123.456, 360.0, 720.0,
1349 ];
1350 for deg in cases {
1351 let a = Angular::from_deg(deg);
1352 assert_relative_eq!(a.default_unit_value(), a.as_rad(), epsilon = 1e-12);
1353 }
1354 }
1355
1356 #[test]
1357 fn test_unit_display_name_and_display() {
1358 assert_eq!(Distance::from_m(1.5).unit_display_name(), "Distance (m)");
1361 assert_eq!(format!("{}", Distance::from_m(2.5)), "2.5");
1362
1363 assert_eq!(Velocity::from_m_per_sec(3.0).unit_display_name(), "Velocity (m/s)");
1364 assert_eq!(format!("{}", Velocity::from_km_per_h(36.0)), "10");
1365
1366 assert_eq!(Acceleration::from_m_per_s2(9.8).unit_display_name(), "Acceleration (m/s²)");
1367 assert_eq!(format!("{}", Acceleration::from_g(1.0)), format!("{}", 9.80665));
1368
1369 assert_eq!(Angular::from_rad(1.0).unit_display_name(), "Angular (rad)");
1370 assert_eq!(format!("{}", Angular::from_deg(180.0)), format!("{}", std::f64::consts::PI));
1371
1372 assert_eq!(AngularVelocity::from_rad_per_second(2.0).unit_display_name(), "AngularVelocity (rad/s)");
1373 assert_eq!(format!("{}", AngularVelocity::from_rad_per_second(2.0)), "2");
1374
1375 assert_eq!(AngularAcceleration::from_rad_per_second2(1.0).unit_display_name(), "AngularAcceleration (rad/s²)");
1376 assert_eq!(format!("{}", AngularAcceleration::from_rad_per_second2(3.0)), "3");
1377
1378 assert_eq!(Coef::new(3.14).unit_display_name(), "Coef");
1379 assert_eq!(format!("{}", Coef::new(3.14)), "3.14");
1380
1381 assert_eq!(Mass::from_kg(1.0).unit_display_name(), "Mass (kg)");
1382 assert_eq!(format!("{}", Mass::from_kg(5.0)), "5");
1383
1384 assert_eq!(Momentum::from_kg_m_s(10.0).unit_display_name(), "Momentum (kg·m/s)");
1385 assert_eq!(format!("{}", Momentum::from_kg_m_s(10.0)), "10");
1386
1387 assert_eq!(AngularMomentum::from_kg_m2_per_second(100.0).unit_display_name(), "AngularMomentum (kg·m²/s)");
1388 assert_eq!(format!("{}", AngularMomentum::from_nms(50.0)), "50");
1389
1390 assert_eq!(Area::from_m2(4.0).unit_display_name(), "Area (m²)");
1391 assert_eq!(format!("{}", Area::from_m2(12.0)), "12");
1392
1393 assert_eq!(Volume::from_m3(8.0).unit_display_name(), "Volume (m³)");
1394 assert_eq!(format!("{}", Volume::from_m3(8.0)), "8");
1395
1396 assert_eq!(MagneticInduction::from_tesla(1.0).unit_display_name(), "MagneticInduction (T)");
1397 assert_eq!(format!("{}", MagneticInduction::from_gauss(10000.0)), "1");
1398
1399 assert_eq!(MagneticMoment::from_am2(1.0).unit_display_name(), "MagneticMoment (A·m²)");
1400 assert_eq!(format!("{}", MagneticMoment::from_am2(2.0)), "2");
1401
1402 assert_eq!(Torque::from_nm(10.0).unit_display_name(), "Torque (N·m)");
1403 assert_eq!(format!("{}", Torque::from_nm(0.0)), "0");
1404
1405 assert_eq!(Energy::from_joule(42.0).unit_display_name(), "Energy (J)");
1406 assert_eq!(format!("{}", Energy::from_joule(0.0)), "0");
1407
1408 assert_eq!(Force::from_newton(100.0).unit_display_name(), "Force (N)");
1409 assert_eq!(format!("{}", Force::from_newton(100.0)), "100");
1410
1411 assert_eq!(Power::from_watt(60.0).unit_display_name(), "Power (W)");
1412 assert_eq!(format!("{}", Power::from_watt(60.0)), "60");
1413
1414 assert_eq!(MagneticAngularVelocity::from_tesla_rad_per_second(1.0).unit_display_name(), "MagneticAngularVelocity (T·rad/s)");
1415 assert_eq!(format!("{}", MagneticAngularVelocity::from_tesla_rad_per_second(1.0)), "1");
1416
1417 assert_eq!(ElectricCurrent::from_a(2.5).unit_display_name(), "ElectricCurrent (A)");
1419 assert_eq!(format!("{}", ElectricCurrent::from_a(2.5)), "2.5");
1420
1421 assert_eq!(ElectricPotential::from_v(12.0).unit_display_name(), "ElectricPotential (V)");
1422 assert_eq!(format!("{}", ElectricPotential::from_v(12.0)), "12");
1423
1424 assert_eq!(ElectricResistance::from_ohm(100.0).unit_display_name(), "ElectricResistance (Ohm)");
1425 assert_eq!(format!("{}", ElectricResistance::from_ohm(100.0)), "100");
1426
1427 assert_eq!(ElectricCharge::from_coulomb(5.0).unit_display_name(), "ElectricCharge (C)");
1428 assert_eq!(format!("{}", ElectricCharge::from_coulomb(5.0)), "5");
1429
1430 assert_eq!(ElectricCapacitance::from_farad(0.001).unit_display_name(), "ElectricCapacitance (F)");
1431 assert_eq!(format!("{}", ElectricCapacitance::from_farad(0.001)), "0.001");
1432
1433 assert_eq!(ElectricConductance::from_siemens(0.01).unit_display_name(), "ElectricConductance (S)");
1434 assert_eq!(format!("{}", ElectricConductance::from_siemens(0.01)), "0.01");
1435 }
1436
1437 #[test]
1438 fn test_vector3_display() {
1439 let v: Vector3<Distance> = Vector3::new(
1440 Distance::from_m(1.0),
1441 Distance::from_m(2.0),
1442 Distance::from_m(3.0),
1443 );
1444 assert_eq!(format!("{}", v), "(1, 2, 3)");
1445 }
1446}
1447
1448impl VectorQuantity for Distance {}
1450impl VectorQuantity for Velocity {}
1451impl VectorQuantity for Acceleration {}
1452impl VectorQuantity for Angular {}
1453impl VectorQuantity for AngularVelocity {}
1454impl VectorQuantity for AngularAcceleration {}
1455impl VectorQuantity for Coef {}
1456impl VectorQuantity for AngularMomentum {}
1457impl VectorQuantity for Momentum {}
1458impl VectorQuantity for MagneticInduction {}
1459impl VectorQuantity for MagneticMoment {}
1460impl VectorQuantity for Torque {}
1461impl VectorQuantity for Force {}
1462impl VectorQuantity for MagneticAngularVelocity {}
1463impl VectorQuantity for HeatFlux {}