1#![cfg_attr(not(feature = "std"), no_std)]
10
11pub use uom;
12
13macro_rules! define_storage_wrappers {
14 ($storage_mod:ident, $storage_ty:ty, [$(($unit_mod:ident, $quantity:ident),)+]) => {
15 pub mod $storage_mod {
16 use core::marker::PhantomData;
17 use serde::{Deserialize, Deserializer, Serialize, Serializer};
18
19 #[cfg(feature = "reflect")]
20 use bevy_reflect::Reflect;
21
22 macro_rules! define_quantity {
23 ($unit_mod_name:ident, $quantity_name:ident) => {
24 #[repr(transparent)]
25 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
26 #[cfg_attr(feature = "reflect", derive(Reflect))]
27 #[cfg_attr(feature = "reflect", reflect(opaque, from_reflect = false))]
28 pub struct $quantity_name(pub(crate) uom::si::$storage_mod::$quantity_name);
29
30 impl $quantity_name {
31 #[inline]
32 pub fn new<U>(value: $storage_ty) -> Self
33 where
34 U: uom::si::$unit_mod_name::Conversion<$storage_ty>,
35 {
36 Self(uom::si::$storage_mod::$quantity_name::new::<U>(value))
37 }
38
39 #[inline]
40 pub fn get<U>(&self) -> $storage_ty
41 where
42 U: uom::si::$unit_mod_name::Conversion<$storage_ty>,
43 {
44 self.0.get::<U>()
45 }
46
47 #[inline]
48 pub fn raw(&self) -> $storage_ty {
49 self.0.value
50 }
51
52 #[inline]
53 pub fn into_uom(self) -> uom::si::$storage_mod::$quantity_name {
54 self.0
55 }
56
57 #[inline]
58 pub fn as_uom(&self) -> &uom::si::$storage_mod::$quantity_name {
59 &self.0
60 }
61
62 #[inline]
63 pub fn from_uom(inner: uom::si::$storage_mod::$quantity_name) -> Self {
64 Self(inner)
65 }
66
67 #[inline]
68 fn from_base_value(
69 value: $storage_ty,
70 ) -> uom::si::$storage_mod::$quantity_name {
71 uom::si::$storage_mod::$quantity_name {
72 dimension: PhantomData,
73 units: PhantomData,
74 value,
75 }
76 }
77 }
78
79 impl Default for $quantity_name {
80 fn default() -> Self {
81 Self(Self::from_base_value(0.0 as $storage_ty))
82 }
83 }
84
85 impl From<uom::si::$storage_mod::$quantity_name> for $quantity_name {
86 fn from(value: uom::si::$storage_mod::$quantity_name) -> Self {
87 Self(value)
88 }
89 }
90
91 impl From<$quantity_name> for uom::si::$storage_mod::$quantity_name {
92 fn from(value: $quantity_name) -> Self {
93 value.0
94 }
95 }
96
97 impl core::ops::Deref for $quantity_name {
98 type Target = uom::si::$storage_mod::$quantity_name;
99
100 fn deref(&self) -> &Self::Target {
101 &self.0
102 }
103 }
104
105 impl core::ops::Add for $quantity_name {
106 type Output = Self;
107
108 fn add(self, rhs: Self) -> Self::Output {
109 Self(Self::from_base_value(self.raw() + rhs.raw()))
110 }
111 }
112
113 impl core::ops::AddAssign for $quantity_name {
114 fn add_assign(&mut self, rhs: Self) {
115 *self = *self + rhs;
116 }
117 }
118
119 impl core::ops::Sub for $quantity_name {
120 type Output = Self;
121
122 fn sub(self, rhs: Self) -> Self::Output {
123 Self(Self::from_base_value(self.raw() - rhs.raw()))
124 }
125 }
126
127 impl core::ops::SubAssign for $quantity_name {
128 fn sub_assign(&mut self, rhs: Self) {
129 *self = *self - rhs;
130 }
131 }
132
133 impl core::ops::Mul<$storage_ty> for $quantity_name {
134 type Output = Self;
135
136 fn mul(self, rhs: $storage_ty) -> Self::Output {
137 Self(Self::from_base_value(self.raw() * rhs))
138 }
139 }
140
141 impl core::ops::MulAssign<$storage_ty> for $quantity_name {
142 fn mul_assign(&mut self, rhs: $storage_ty) {
143 *self = *self * rhs;
144 }
145 }
146
147 impl core::ops::Div<$storage_ty> for $quantity_name {
148 type Output = Self;
149
150 fn div(self, rhs: $storage_ty) -> Self::Output {
151 Self(Self::from_base_value(self.raw() / rhs))
152 }
153 }
154
155 impl core::ops::DivAssign<$storage_ty> for $quantity_name {
156 fn div_assign(&mut self, rhs: $storage_ty) {
157 *self = *self / rhs;
158 }
159 }
160
161 impl core::ops::Neg for $quantity_name {
162 type Output = Self;
163
164 fn neg(self) -> Self::Output {
165 Self(Self::from_base_value(-self.raw()))
166 }
167 }
168
169 impl Serialize for $quantity_name {
170 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
171 where
172 S: Serializer,
173 {
174 self.raw().serialize(serializer)
175 }
176 }
177
178 impl<'de> Deserialize<'de> for $quantity_name {
179 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
180 where
181 D: Deserializer<'de>,
182 {
183 let value = <$storage_ty>::deserialize(deserializer)?;
184 Ok(Self(Self::from_base_value(value)))
185 }
186 }
187
188 impl bincode::Encode for $quantity_name {
189 fn encode<E: bincode::enc::Encoder>(
190 &self,
191 encoder: &mut E,
192 ) -> Result<(), bincode::error::EncodeError> {
193 bincode::Encode::encode(&self.raw(), encoder)
194 }
195 }
196
197 impl<Context> bincode::Decode<Context> for $quantity_name {
198 fn decode<D: bincode::de::Decoder<Context = Context>>(
199 decoder: &mut D,
200 ) -> Result<Self, bincode::error::DecodeError> {
201 let value: $storage_ty = bincode::Decode::decode(decoder)?;
202 Ok(Self(Self::from_base_value(value)))
203 }
204 }
205
206 impl<'de, Context> bincode::BorrowDecode<'de, Context> for $quantity_name {
207 fn borrow_decode<D: bincode::de::BorrowDecoder<'de, Context = Context>>(
208 decoder: &mut D,
209 ) -> Result<Self, bincode::error::DecodeError> {
210 <Self as bincode::Decode<Context>>::decode(decoder)
211 }
212 }
213
214 #[cfg(feature = "reflect")]
215 impl bevy_reflect::FromReflect for $quantity_name {
216 fn from_reflect(
217 reflect: &dyn bevy_reflect::PartialReflect,
218 ) -> Option<Self> {
219 if let Some(existing) = reflect.try_downcast_ref::<Self>() {
220 return Some(*existing);
221 }
222
223 reflect
224 .try_downcast_ref::<$storage_ty>()
225 .map(|value| Self(Self::from_base_value(*value)))
226 }
227 }
228 };
229 }
230
231 $(define_quantity!($unit_mod, $quantity);)+
232 }
233 };
234}
235
236pub mod si {
237 pub use uom::si::{
238 ISQ, SI, absement, acceleration, action, amount_of_substance, angle, angular_absement,
239 angular_acceleration, angular_jerk, angular_momentum, angular_velocity, area,
240 areal_density_of_states, areal_heat_capacity, areal_mass_density, areal_number_density,
241 areal_number_rate, available_energy, capacitance, catalytic_activity,
242 catalytic_activity_concentration, curvature, diffusion_coefficient, dynamic_viscosity,
243 electric_charge, electric_charge_areal_density, electric_charge_linear_density,
244 electric_charge_volumetric_density, electric_current, electric_current_density,
245 electric_dipole_moment, electric_displacement_field, electric_field, electric_flux,
246 electric_permittivity, electric_potential, electric_quadrupole_moment,
247 electrical_conductance, electrical_conductivity, electrical_mobility,
248 electrical_resistance, electrical_resistivity, energy, force, frequency, frequency_drift,
249 heat_capacity, heat_flux_density, heat_transfer, inductance, information, information_rate,
250 inverse_velocity, jerk, kinematic_viscosity, length, linear_density_of_states,
251 linear_mass_density, linear_number_density, linear_number_rate, linear_power_density,
252 luminance, luminous_intensity, magnetic_field_strength, magnetic_flux,
253 magnetic_flux_density, magnetic_moment, magnetic_permeability, mass, mass_concentration,
254 mass_density, mass_flux, mass_per_energy, mass_rate, molality, molar_concentration,
255 molar_energy, molar_flux, molar_heat_capacity, molar_mass, molar_radioactivity,
256 molar_volume, moment_of_inertia, momentum, power, power_rate, pressure, radiant_exposure,
257 radioactivity, ratio, reciprocal_length, solid_angle, specific_area,
258 specific_heat_capacity, specific_power, specific_radioactivity, specific_volume,
259 surface_electric_current_density, surface_tension, temperature_coefficient,
260 temperature_gradient, temperature_interval, thermal_conductance, thermal_conductivity,
261 thermal_resistance, thermodynamic_temperature, time, torque, velocity, volume, volume_rate,
262 volumetric_density_of_states, volumetric_heat_capacity, volumetric_number_density,
263 volumetric_number_rate, volumetric_power_density,
264 };
265
266 define_storage_wrappers! {
267 f32,
268 f32,
269 [
270 (absement, Absement),
271 (acceleration, Acceleration),
272 (action, Action),
273 (amount_of_substance, AmountOfSubstance),
274 (angle, Angle),
275 (angular_absement, AngularAbsement),
276 (angular_acceleration, AngularAcceleration),
277 (angular_jerk, AngularJerk),
278 (angular_momentum, AngularMomentum),
279 (angular_velocity, AngularVelocity),
280 (area, Area),
281 (areal_density_of_states, ArealDensityOfStates),
282 (areal_heat_capacity, ArealHeatCapacity),
283 (areal_mass_density, ArealMassDensity),
284 (areal_number_density, ArealNumberDensity),
285 (areal_number_rate, ArealNumberRate),
286 (available_energy, AvailableEnergy),
287 (capacitance, Capacitance),
288 (catalytic_activity, CatalyticActivity),
289 (catalytic_activity_concentration, CatalyticActivityConcentration),
290 (curvature, Curvature),
291 (diffusion_coefficient, DiffusionCoefficient),
292 (dynamic_viscosity, DynamicViscosity),
293 (electric_charge, ElectricCharge),
294 (electric_charge_areal_density, ElectricChargeArealDensity),
295 (electric_charge_linear_density, ElectricChargeLinearDensity),
296 (electric_charge_volumetric_density, ElectricChargeVolumetricDensity),
297 (electric_current, ElectricCurrent),
298 (electric_current_density, ElectricCurrentDensity),
299 (electric_dipole_moment, ElectricDipoleMoment),
300 (electric_displacement_field, ElectricDisplacementField),
301 (electric_field, ElectricField),
302 (electric_flux, ElectricFlux),
303 (electric_permittivity, ElectricPermittivity),
304 (electric_potential, ElectricPotential),
305 (electric_quadrupole_moment, ElectricQuadrupoleMoment),
306 (electrical_conductance, ElectricalConductance),
307 (electrical_conductivity, ElectricalConductivity),
308 (electrical_mobility, ElectricalMobility),
309 (electrical_resistance, ElectricalResistance),
310 (electrical_resistivity, ElectricalResistivity),
311 (energy, Energy),
312 (force, Force),
313 (frequency, Frequency),
314 (frequency_drift, FrequencyDrift),
315 (heat_capacity, HeatCapacity),
316 (heat_flux_density, HeatFluxDensity),
317 (heat_transfer, HeatTransfer),
318 (inductance, Inductance),
319 (information, Information),
320 (information_rate, InformationRate),
321 (inverse_velocity, InverseVelocity),
322 (jerk, Jerk),
323 (kinematic_viscosity, KinematicViscosity),
324 (length, Length),
325 (linear_density_of_states, LinearDensityOfStates),
326 (linear_mass_density, LinearMassDensity),
327 (linear_number_density, LinearNumberDensity),
328 (linear_number_rate, LinearNumberRate),
329 (linear_power_density, LinearPowerDensity),
330 (luminance, Luminance),
331 (luminous_intensity, LuminousIntensity),
332 (magnetic_field_strength, MagneticFieldStrength),
333 (magnetic_flux, MagneticFlux),
334 (magnetic_flux_density, MagneticFluxDensity),
335 (magnetic_moment, MagneticMoment),
336 (magnetic_permeability, MagneticPermeability),
337 (mass, Mass),
338 (mass_concentration, MassConcentration),
339 (mass_density, MassDensity),
340 (mass_flux, MassFlux),
341 (mass_per_energy, MassPerEnergy),
342 (mass_rate, MassRate),
343 (molality, Molality),
344 (molar_concentration, MolarConcentration),
345 (molar_energy, MolarEnergy),
346 (molar_flux, MolarFlux),
347 (molar_heat_capacity, MolarHeatCapacity),
348 (molar_mass, MolarMass),
349 (molar_radioactivity, MolarRadioactivity),
350 (molar_volume, MolarVolume),
351 (moment_of_inertia, MomentOfInertia),
352 (momentum, Momentum),
353 (power, Power),
354 (power_rate, PowerRate),
355 (pressure, Pressure),
356 (radiant_exposure, RadiantExposure),
357 (radioactivity, Radioactivity),
358 (ratio, Ratio),
359 (reciprocal_length, ReciprocalLength),
360 (solid_angle, SolidAngle),
361 (specific_area, SpecificArea),
362 (specific_heat_capacity, SpecificHeatCapacity),
363 (specific_power, SpecificPower),
364 (specific_radioactivity, SpecificRadioactivity),
365 (specific_volume, SpecificVolume),
366 (surface_electric_current_density, SurfaceElectricCurrentDensity),
367 (surface_tension, SurfaceTension),
368 (temperature_coefficient, TemperatureCoefficient),
369 (temperature_gradient, TemperatureGradient),
370 (temperature_interval, TemperatureInterval),
371 (thermal_conductance, ThermalConductance),
372 (thermal_conductivity, ThermalConductivity),
373 (thermal_resistance, ThermalResistance),
374 (thermodynamic_temperature, ThermodynamicTemperature),
375 (time, Time),
376 (torque, Torque),
377 (velocity, Velocity),
378 (volume, Volume),
379 (volume_rate, VolumeRate),
380 (volumetric_density_of_states, VolumetricDensityOfStates),
381 (volumetric_heat_capacity, VolumetricHeatCapacity),
382 (volumetric_number_density, VolumetricNumberDensity),
383 (volumetric_number_rate, VolumetricNumberRate),
384 (volumetric_power_density, VolumetricPowerDensity),
385 ]
386 }
387
388 define_storage_wrappers! {
389 f64,
390 f64,
391 [
392 (absement, Absement),
393 (acceleration, Acceleration),
394 (action, Action),
395 (amount_of_substance, AmountOfSubstance),
396 (angle, Angle),
397 (angular_absement, AngularAbsement),
398 (angular_acceleration, AngularAcceleration),
399 (angular_jerk, AngularJerk),
400 (angular_momentum, AngularMomentum),
401 (angular_velocity, AngularVelocity),
402 (area, Area),
403 (areal_density_of_states, ArealDensityOfStates),
404 (areal_heat_capacity, ArealHeatCapacity),
405 (areal_mass_density, ArealMassDensity),
406 (areal_number_density, ArealNumberDensity),
407 (areal_number_rate, ArealNumberRate),
408 (available_energy, AvailableEnergy),
409 (capacitance, Capacitance),
410 (catalytic_activity, CatalyticActivity),
411 (catalytic_activity_concentration, CatalyticActivityConcentration),
412 (curvature, Curvature),
413 (diffusion_coefficient, DiffusionCoefficient),
414 (dynamic_viscosity, DynamicViscosity),
415 (electric_charge, ElectricCharge),
416 (electric_charge_areal_density, ElectricChargeArealDensity),
417 (electric_charge_linear_density, ElectricChargeLinearDensity),
418 (electric_charge_volumetric_density, ElectricChargeVolumetricDensity),
419 (electric_current, ElectricCurrent),
420 (electric_current_density, ElectricCurrentDensity),
421 (electric_dipole_moment, ElectricDipoleMoment),
422 (electric_displacement_field, ElectricDisplacementField),
423 (electric_field, ElectricField),
424 (electric_flux, ElectricFlux),
425 (electric_permittivity, ElectricPermittivity),
426 (electric_potential, ElectricPotential),
427 (electric_quadrupole_moment, ElectricQuadrupoleMoment),
428 (electrical_conductance, ElectricalConductance),
429 (electrical_conductivity, ElectricalConductivity),
430 (electrical_mobility, ElectricalMobility),
431 (electrical_resistance, ElectricalResistance),
432 (electrical_resistivity, ElectricalResistivity),
433 (energy, Energy),
434 (force, Force),
435 (frequency, Frequency),
436 (frequency_drift, FrequencyDrift),
437 (heat_capacity, HeatCapacity),
438 (heat_flux_density, HeatFluxDensity),
439 (heat_transfer, HeatTransfer),
440 (inductance, Inductance),
441 (information, Information),
442 (information_rate, InformationRate),
443 (inverse_velocity, InverseVelocity),
444 (jerk, Jerk),
445 (kinematic_viscosity, KinematicViscosity),
446 (length, Length),
447 (linear_density_of_states, LinearDensityOfStates),
448 (linear_mass_density, LinearMassDensity),
449 (linear_number_density, LinearNumberDensity),
450 (linear_number_rate, LinearNumberRate),
451 (linear_power_density, LinearPowerDensity),
452 (luminance, Luminance),
453 (luminous_intensity, LuminousIntensity),
454 (magnetic_field_strength, MagneticFieldStrength),
455 (magnetic_flux, MagneticFlux),
456 (magnetic_flux_density, MagneticFluxDensity),
457 (magnetic_moment, MagneticMoment),
458 (magnetic_permeability, MagneticPermeability),
459 (mass, Mass),
460 (mass_concentration, MassConcentration),
461 (mass_density, MassDensity),
462 (mass_flux, MassFlux),
463 (mass_per_energy, MassPerEnergy),
464 (mass_rate, MassRate),
465 (molality, Molality),
466 (molar_concentration, MolarConcentration),
467 (molar_energy, MolarEnergy),
468 (molar_flux, MolarFlux),
469 (molar_heat_capacity, MolarHeatCapacity),
470 (molar_mass, MolarMass),
471 (molar_radioactivity, MolarRadioactivity),
472 (molar_volume, MolarVolume),
473 (moment_of_inertia, MomentOfInertia),
474 (momentum, Momentum),
475 (power, Power),
476 (power_rate, PowerRate),
477 (pressure, Pressure),
478 (radiant_exposure, RadiantExposure),
479 (radioactivity, Radioactivity),
480 (ratio, Ratio),
481 (reciprocal_length, ReciprocalLength),
482 (solid_angle, SolidAngle),
483 (specific_area, SpecificArea),
484 (specific_heat_capacity, SpecificHeatCapacity),
485 (specific_power, SpecificPower),
486 (specific_radioactivity, SpecificRadioactivity),
487 (specific_volume, SpecificVolume),
488 (surface_electric_current_density, SurfaceElectricCurrentDensity),
489 (surface_tension, SurfaceTension),
490 (temperature_coefficient, TemperatureCoefficient),
491 (temperature_gradient, TemperatureGradient),
492 (temperature_interval, TemperatureInterval),
493 (thermal_conductance, ThermalConductance),
494 (thermal_conductivity, ThermalConductivity),
495 (thermal_resistance, ThermalResistance),
496 (thermodynamic_temperature, ThermodynamicTemperature),
497 (time, Time),
498 (torque, Torque),
499 (velocity, Velocity),
500 (volume, Volume),
501 (volume_rate, VolumeRate),
502 (volumetric_density_of_states, VolumetricDensityOfStates),
503 (volumetric_heat_capacity, VolumetricHeatCapacity),
504 (volumetric_number_density, VolumetricNumberDensity),
505 (volumetric_number_rate, VolumetricNumberRate),
506 (volumetric_power_density, VolumetricPowerDensity),
507 ]
508 }
509}
510
511#[cfg(all(test, feature = "reflect"))]
512mod tests {
513 use super::si::f32::Velocity;
514 use super::si::velocity::{kilometer_per_hour, meter_per_second};
515 use bevy_reflect::{PartialReflect, Reflect, ReflectRef};
516
517 #[derive(Reflect)]
518 #[reflect(from_reflect = false)]
519 struct Msg {
520 speed: Velocity,
521 }
522
523 #[test]
524 fn reflect_velocity_as_opaque_base_value() {
525 let msg = Msg {
526 speed: Velocity::new::<kilometer_per_hour>(36.0),
527 };
528
529 assert!(matches!(
530 msg.speed.as_partial_reflect().reflect_ref(),
531 ReflectRef::Opaque(_)
532 ));
533 assert_eq!(msg.speed.get::<meter_per_second>(), 10.0);
534
535 let speed_reflected = match msg.as_partial_reflect().reflect_ref() {
536 ReflectRef::Struct(s) => s.field("speed").expect("speed field should exist"),
537 _ => panic!("expected struct reflection"),
538 };
539
540 let speed = speed_reflected
541 .try_downcast_ref::<Velocity>()
542 .expect("speed should downcast to cu29_units::si::f32::Velocity");
543 assert_eq!(speed.raw(), 10.0);
544 assert_eq!(speed.get::<meter_per_second>(), 10.0);
545 }
546}