pub trait IsQuantityFunction:
DynClone
+ Sync
+ Send
+ Any
+ Serialize
+ Deserialize {
// Required method
fn call(&self, influencing_factors: &[DynQuantity<f64>]) -> DynQuantity<f64>;
}Expand description
Trait used to construct variable quantities whose value is a (pure) function of other quantities.
Implementing this trait for a type marks it as being a variable quantity, whose value can change under the influence of other quantities. For example, a resistance can be a function of temperature:
use dyn_quantity::{DynQuantity, PredefUnit, Unit};
use var_quantity::IsQuantityFunction;
// The serde annotations are just here because the doctests of this crate use
// the serde feature - they are not needed if the serde feature is disabled.
#[derive(Clone, serde::Deserialize, serde::Serialize)]
struct Resistance;
// Again, the macro annotation is just here because of the serde feature
#[typetag::serde]
impl IsQuantityFunction for Resistance {
fn call(&self, influencing_factors: &[DynQuantity<f64>]) -> DynQuantity<f64> {
let mut temperature = 0.0;
let temperature_unit: Unit = PredefUnit::Temperature.into();
for f in influencing_factors.iter() {
if f.unit == temperature_unit {
temperature = f.value;
break;
}
}
return DynQuantity::new(1.0 + temperature / 100.0, PredefUnit::ElectricResistance);
}
}
// Influencing factors
let infl1 = &[DynQuantity::new(6.0, PredefUnit::ElectricCurrent)];
let infl2 = &[
DynQuantity::new(6.0, PredefUnit::ElectricCurrent),
DynQuantity::new(20.0, PredefUnit::Temperature),
];
let resistance = Resistance {};
assert_eq!(DynQuantity::new(1.0, PredefUnit::ElectricResistance), resistance.call(&[]));
assert_eq!(DynQuantity::new(1.0, PredefUnit::ElectricResistance), resistance.call(infl1));
assert_eq!(DynQuantity::new(1.2, PredefUnit::ElectricResistance), resistance.call(infl2));An important constraint which unfortunately cannot be covered by the type
system is that the DynQuantity<f64> returned by IsQuantityFunction::call
must always have the same Unit field. See the Features section
and the docstring of VarQuantity for details.
§Features
When the serde feature is enabled, any type implementing IsQuantityFunction
can be serialized / deserialized as a trait object using the
typetag crate. This has the following
implications:
IsQuantityFunction::callcannot return a generic type (limitation of typetag), which is why the dynamicDynQuantitytype is used.- When implementing
IsQuantityFunctionfor a type, the#[typetag::serde]annotation must be applied to theimplblock (see example).
In turn, this feature enables serialization / deserialization of VarQuantity
without the need to specify the underlying function type in advance.
Required Methods§
Sourcefn call(&self, influencing_factors: &[DynQuantity<f64>]) -> DynQuantity<f64>
fn call(&self, influencing_factors: &[DynQuantity<f64>]) -> DynQuantity<f64>
Returns a quantity as a function of influencing_factors. See the
IsQuantityFunction trait docstring for examples.