use dyn_quantity::{DynQuantity, Unit};
#[cfg(feature = "serde")]
use dyn_quantity::serialize_quantity;
use crate::{IsQuantityFunction, filter_unary_function};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Linear {
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_quantity"))]
slope: DynQuantity<f64>,
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_quantity"))]
base_value: DynQuantity<f64>,
}
impl Linear {
pub fn new(slope: DynQuantity<f64>, base_value: DynQuantity<f64>) -> Self {
return Self { slope, base_value };
}
pub fn base_value(&self) -> &DynQuantity<f64> {
return &self.base_value;
}
pub fn slope(&self) -> &DynQuantity<f64> {
return &self.slope;
}
pub fn influencing_factor_unit(&self) -> Unit {
return self.base_value.unit / self.slope.unit;
}
pub fn output_unit(&self) -> Unit {
return self.base_value.unit;
}
}
#[cfg_attr(feature = "serde", typetag::serde)]
impl IsQuantityFunction for Linear {
fn call(&self, conditions: &[DynQuantity<f64>]) -> DynQuantity<f64> {
return filter_unary_function(
conditions,
self.influencing_factor_unit(),
|input| {
DynQuantity::new(
self.base_value.value + self.slope.value * input.value,
self.base_value.unit,
)
},
|| self.base_value,
);
}
fn dyn_eq(&self, other: &dyn IsQuantityFunction) -> bool {
(other as &dyn std::any::Any).downcast_ref::<Self>() == Some(self)
}
}
#[cfg(feature = "serde")]
#[cfg_attr(feature = "serde", typetag::serde)]
impl IsQuantityFunction for crate::ClampedQuantity<Linear> {
fn call(&self, conditions: &[DynQuantity<f64>]) -> DynQuantity<f64> {
return self.call_clamped(conditions);
}
fn dyn_eq(&self, other: &dyn IsQuantityFunction) -> bool {
(other as &dyn std::any::Any).downcast_ref::<Self>() == Some(self)
}
}