1use crate::{errors::RuntimeUnitError, units_base::{UnitBase, UnitDefinition}, Units};
2use core::ops::{Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign };
3
4
5pub(crate) trait IsScalarQuantity
6{
7 fn value(&self) -> f64;
8 fn unit(&self) -> UnitDefinition;
9}
10
11pub trait ArbitraryQuantity where Self: Sized + Div<f64> + Mul<f64> + DivAssign<f64> + MulAssign<f64> + Div<Self> + Mul<Self> + AddAssign<Self> + SubAssign<Self> + DivAssign<Self>
15{
16 fn unit(&self) -> UnitDefinition;
18 fn unit_mut(&mut self) -> &mut UnitDefinition;
20 fn try_convert(&self, unit: UnitDefinition) -> Result<Self, RuntimeUnitError>;
22 #[inline]
23 fn try_convert_unit(&self, unit: Units) -> Result<Self, RuntimeUnitError>
25 {
26 self.try_convert(unit.into())
27 }
28 fn try_convert_mut(&mut self, unit: UnitDefinition) -> Result<(), RuntimeUnitError>;
30 fn convert(&self, unit: UnitDefinition) -> Self;
32 fn convert_mut(&mut self, unit: UnitDefinition);
34}
35
36pub trait FixedQuantity<UnitType: Unit> where Self: Sized + Div<f64> + Mul<f64> + DivAssign<f64> + MulAssign<f64> + AddAssign<Self> + SubAssign<Self>
40{
41 fn unit(&self) -> UnitType;
43 fn unit_mut(&mut self) -> &mut UnitType;
45 fn convert(&self, unit: UnitType) -> Self;
47 fn convert_mut(&mut self, unit: UnitType);
49 fn try_convert(&self, unit: crate::Units) -> Result<Self, RuntimeUnitError> where Self: Sized;
51}
52
53pub trait FixedSliceQuantity<UnitType: Unit, Element>
57{
58 fn unit(&self) -> UnitType;
60 fn values(&self) -> &[Element];
62 fn values_mut(&mut self) -> &mut [Element];
64 fn len(&self) -> usize;
66 fn convert(&self, unit: UnitType) -> Self;
68 fn convert_mut(&mut self, unit: UnitType);
70 fn try_convert(&self, unit: Units) -> Result<Self, RuntimeUnitError> where Self: Sized;
72}
73
74
75pub trait Unit where Self:Sized
79{
80 fn definition(&self) -> UnitDefinition;
82
83 #[inline]
85 fn try_convert(&self, unit: UnitDefinition) -> Result<f64, RuntimeUnitError>
86 {
87 let definition = self.definition();
88 if definition.is_convertible(unit)
89 {
90 Ok(unit.multiplier() / definition.multiplier())
91 }
92 else
93 {
94 Err(RuntimeUnitError::IncompatibleUnitConversion(format!("Could not convert from base units of {} to {}", definition.unit_string(), unit.unit_string())))
95 }
96 }
97 #[inline]
99 fn convert_unchecked(&self, unit: Self) -> f64
100 {
101 let definition = self.definition();
102 definition.multiplier() / unit.definition().multiplier()
103 }
104}