fastsim_core/vehicle/
traits.rs

1//! Traits to be used in vehicle and nested subsystems and components
2
3use super::*;
4
5#[derive(
6    Default, Deserialize, Serialize, Debug, Clone, PartialEq, IsVariant, derive_more::From, TryInto,
7)]
8/// Governs which side effect to trigger when setting mass
9pub enum MassSideEffect {
10    /// To be used when [MassSideEffect] is not applicable
11    #[default]
12    None,
13    /// Set the extensive parameter -- e.g. energy, power -- as a side effect
14    Extensive,
15    /// Set the intensive parameter -- e.g. specific power, specific energy -- as a side effect
16    Intensive,
17}
18
19impl TryFrom<String> for MassSideEffect {
20    type Error = anyhow::Error;
21    fn try_from(value: String) -> anyhow::Result<MassSideEffect> {
22        let mass_side_effect = match value.as_str() {
23            "None" => MassSideEffect::None,
24            "Extensive" => MassSideEffect::Extensive,
25            "Intensive" => MassSideEffect::Intensive,
26            _ => {
27                bail!(format!(
28                    "`MassSideEffect` must be 'Intensive', 'Extensive', or 'None'. "
29                ))
30            }
31        };
32        Ok(mass_side_effect)
33    }
34}
35
36pub trait Mass {
37    /// Returns mass of Self, either from `self.mass` or
38    /// the derived from fields that store mass data. `Mass::mass` also checks that
39    /// derived mass, if Some, is same as `self.mass`.
40    fn mass(&self) -> anyhow::Result<Option<si::Mass>>;
41
42    /// Sets component mass to `mass`, or if `None` is provided for `mass`,
43    /// sets mass based on other component parameters (e.g. power and power
44    /// density, sum of fields containing mass)
45    fn set_mass(
46        &mut self,
47        new_mass: Option<si::Mass>,
48        side_effect: MassSideEffect,
49    ) -> anyhow::Result<()>;
50
51    /// Returns derived mass (e.g. sum of mass fields, or
52    /// calculation involving mass specific properties).  If
53    fn derived_mass(&self) -> anyhow::Result<Option<si::Mass>>;
54
55    /// Sets all fields that are used in calculating derived mass to `None`.
56    /// Does not touch `self.mass`.
57    fn expunge_mass_fields(&mut self);
58
59    /// Sets any mass-specific property with appropriate side effects
60    fn set_mass_specific_property(&mut self) -> anyhow::Result<()> {
61        // TODO: remove this default implementation when this method has been universally implemented.
62        // For structs without specific properties (e.g. `Vehicle`), return an error
63        Ok(())
64    }
65}