use crate::units::convertible::Convertible;
#[derive(Debug, Clone)]
pub struct UnitsConverter<N>(pub(crate) UnitsConverterInner<N>)
where
N: Convertible;
impl<N> UnitsConverter<N>
where
N: Convertible,
{
pub fn convert(&self, value: &N) -> N {
self.0.convert(value)
}
}
#[derive(Debug, Clone)]
pub(crate) enum UnitsConverterInner<N>
where
N: Convertible,
{
Proportional(ProportionalConverter<N>),
Reciprocal(ReciprocalConverter<N>),
Offset(OffsetConverter<N>),
}
impl<N> UnitsConverterInner<N>
where
N: Convertible,
{
fn convert(&self, value: &N) -> N {
match self {
UnitsConverterInner::Proportional(converter) => converter.convert(value),
UnitsConverterInner::Reciprocal(converter) => converter.convert(value),
UnitsConverterInner::Offset(converter) => converter.convert(value),
}
}
}
#[derive(Debug, Clone)]
pub(crate) struct ReciprocalConverter<N>
where
N: Convertible,
{
pub(crate) proportional: ProportionalConverter<N>,
}
impl<N> ReciprocalConverter<N>
where
N: Convertible,
{
pub(crate) fn convert(&self, value: &N) -> N {
self.proportional.convert(value).reciprocal()
}
}
#[derive(Debug, Clone)]
pub(crate) struct OffsetConverter<N>
where
N: Convertible,
{
pub(crate) proportional: ProportionalConverter<N>,
pub(crate) offset: N,
}
impl<N> OffsetConverter<N>
where
N: Convertible,
{
pub(crate) fn convert(&self, value: &N) -> N {
self.proportional.convert(value).add_refs(&self.offset)
}
}
#[derive(Debug, Clone)]
pub(crate) struct ProportionalConverter<N>
where
N: Convertible,
{
pub(crate) conversion_rate: N,
}
impl<N> ProportionalConverter<N>
where
N: Convertible,
{
pub fn convert(&self, value: &N) -> N {
value.mul_refs(&self.conversion_rate)
}
}