From 3af02ece520ca6adbe1b34c5f8df0c0503942737 Mon Sep 17 00:00:00 2001 From: Michael O'Keefe Date: Fri, 15 Nov 2024 12:34:41 -0700 Subject: [PATCH 1/2] Begin adding _phantom data to prevent direct instantiation outside of ::new() --- fastsim-core/src/simdrive.rs | 28 ++++++++++--------- .../src/vehicle/powertrain/fuel_converter.rs | 2 +- fastsim-core/src/vehicle/vehicle_model.rs | 22 +++++---------- .../vehicle_model/fastsim2_interface.rs | 1 + 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/fastsim-core/src/simdrive.rs b/fastsim-core/src/simdrive.rs index 8878e6e5..4c3eb3dd 100644 --- a/fastsim-core/src/simdrive.rs +++ b/fastsim-core/src/simdrive.rs @@ -18,6 +18,10 @@ pub struct SimParams { pub trace_miss_opts: TraceMissOptions, /// whether to use FASTSim-2 style air density pub f2_air_density: bool, + // phantom private field to prevent direct instantiation in other modules + #[serde(skip)] + #[api(skip_get, skip_set)] + pub _phantom: PhantomData<()>, } impl SerdeAPI for SimParams {} @@ -32,6 +36,7 @@ impl Default for SimParams { trace_miss_tol: Default::default(), trace_miss_opts: Default::default(), f2_air_density: true, + _phantom: PhantomData, } } } @@ -39,11 +44,11 @@ impl Default for SimParams { #[fastsim_api( #[new] fn __new__(veh: Vehicle, cyc: Cycle, sim_params: Option) -> anyhow::Result { - Ok(SimDrive{ + Ok(SimDrive::new( veh, cyc, - sim_params: sim_params.unwrap_or_default(), - }) + sim_params, + )) } /// Run vehicle simulation once @@ -72,6 +77,10 @@ pub struct SimDrive { pub veh: Vehicle, pub cyc: Cycle, pub sim_params: SimParams, + // phantom private field to prevent direct instantiation in other modules + #[serde(skip)] + #[api(skip_get, skip_set)] + _phantom: PhantomData<()>, } impl SerdeAPI for SimDrive {} @@ -92,6 +101,7 @@ impl SimDrive { veh, cyc, sim_params: sim_params.unwrap_or_default(), + _phantom: PhantomData, } } @@ -520,11 +530,7 @@ mod tests { fn test_sim_drive_conv() { let _veh = mock_conv_veh(); let _cyc = Cycle::from_resource("udds.csv", false).unwrap(); - let mut sd = SimDrive { - veh: _veh, - cyc: _cyc, - sim_params: Default::default(), - }; + let mut sd = SimDrive::new(_veh, _cyc, Default::default()); sd.walk().unwrap(); assert!(sd.veh.state.i == sd.cyc.len()); assert!(sd.veh.fc().unwrap().state.energy_fuel > si::Energy::ZERO); @@ -535,11 +541,7 @@ mod tests { fn test_sim_drive_hev() { let _veh = mock_hev(); let _cyc = Cycle::from_resource("udds.csv", false).unwrap(); - let mut sd = SimDrive { - veh: _veh, - cyc: _cyc, - sim_params: Default::default(), - }; + let mut sd = SimDrive::new(_veh, _cyc, Default::default()); sd.walk().unwrap(); assert!(sd.veh.state.i == sd.cyc.len()); assert!(sd.veh.fc().unwrap().state.energy_fuel > si::Energy::ZERO); diff --git a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs index 1377d004..8acf52c3 100755 --- a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs +++ b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs @@ -87,8 +87,8 @@ pub struct FuelConverter { #[serde(default)] #[serde(skip_serializing_if = "FuelConverterStateHistoryVec::is_empty")] pub history: FuelConverterStateHistoryVec, - #[serde(skip)] // phantom private field to prevent direct instantiation in other modules + #[serde(skip)] #[api(skip_get, skip_set)] pub(in super::super) _phantom: PhantomData<()>, } diff --git a/fastsim-core/src/vehicle/vehicle_model.rs b/fastsim-core/src/vehicle/vehicle_model.rs index f0e8aa95..d1640ca0 100644 --- a/fastsim-core/src/vehicle/vehicle_model.rs +++ b/fastsim-core/src/vehicle/vehicle_model.rs @@ -150,6 +150,10 @@ pub struct Vehicle { #[serde(default)] #[serde(skip_serializing_if = "VehicleStateHistoryVec::is_empty")] pub history: VehicleStateHistoryVec, + // phantom private field to prevent direct instantiation in other modules + #[serde(skip)] + #[api(skip_get, skip_set)] + _phantom: PhantomData<()>, } impl Mass for Vehicle { @@ -606,11 +610,7 @@ pub(crate) mod tests { fn test_to_fastsim2_conv() { let veh = mock_conv_veh(); let cyc = crate::drive_cycle::Cycle::from_resource("udds.csv", false).unwrap(); - let sd = crate::simdrive::SimDrive { - veh, - cyc, - sim_params: Default::default(), - }; + let sd = crate::simdrive::SimDrive::new(veh, cyc, Default::default()); let mut sd2 = sd.to_fastsim2().unwrap(); sd2.sim_drive(None, None).unwrap(); } @@ -620,11 +620,7 @@ pub(crate) mod tests { fn test_to_fastsim2_hev() { let veh = mock_hev(); let cyc = crate::drive_cycle::Cycle::from_resource("udds.csv", false).unwrap(); - let sd = crate::simdrive::SimDrive { - veh, - cyc, - sim_params: Default::default(), - }; + let sd = crate::simdrive::SimDrive::new(veh, cyc, Default::default()); let mut sd2 = sd.to_fastsim2().unwrap(); sd2.sim_drive(None, None).unwrap(); } @@ -634,11 +630,7 @@ pub(crate) mod tests { fn test_to_fastsim2_bev() { let veh = mock_bev(); let cyc = crate::drive_cycle::Cycle::from_resource("udds.csv", false).unwrap(); - let sd = crate::simdrive::SimDrive { - veh, - cyc, - sim_params: Default::default(), - }; + let sd = crate::simdrive::SimDrive::new(veh, cyc, Default::default()); let mut sd2 = sd.to_fastsim2().unwrap(); sd2.sim_drive(None, None).unwrap(); } diff --git a/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs b/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs index a8935d17..71ff3969 100644 --- a/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs +++ b/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs @@ -22,6 +22,7 @@ impl TryFrom for Vehicle { save_interval, history: Default::default(), mass: Some(f2veh.veh_kg * uc::KG), + _phantom: PhantomData, }; f3veh.expunge_mass_fields(); f3veh.init().with_context(|| anyhow!(format_dbg!()))?; From 0c34794a41c26a064fc809e3b5901ceab4d830c5 Mon Sep 17 00:00:00 2001 From: Michael O'Keefe Date: Fri, 6 Dec 2024 11:59:59 -0700 Subject: [PATCH 2/2] Annotate all pub struct with #[non_exhaustive] This prevents code outside of the crate from constructing the given structs using a StructExpression (i.e., MyStruct { ... }). I have tested and confirmed that, for example, I cannot instatiate a struct from the fastsim-cli crate. This was deemed to be a little less convoluted than using a PhantomData typed method which essentially does the same thing. --- fastsim-core/src/air_properties.rs | 1 + fastsim-core/src/drive_cycle.rs | 2 ++ fastsim-core/src/simdrive.rs | 13 ++------- fastsim-core/src/vehicle/bev.rs | 1 + fastsim-core/src/vehicle/cabin.rs | 1 + fastsim-core/src/vehicle/chassis.rs | 1 + fastsim-core/src/vehicle/conv.rs | 1 + fastsim-core/src/vehicle/hev.rs | 5 ++++ .../vehicle/powertrain/electric_machine.rs | 29 +++++++++++-------- .../src/vehicle/powertrain/fuel_converter.rs | 7 ++--- .../src/vehicle/powertrain/fuel_storage.rs | 1 + .../powertrain/reversible_energy_storage.rs | 2 ++ .../src/vehicle/powertrain/transmission.rs | 2 ++ fastsim-core/src/vehicle/vehicle_model.rs | 6 ++-- .../vehicle_model/fastsim2_interface.rs | 3 -- 15 files changed, 42 insertions(+), 33 deletions(-) diff --git a/fastsim-core/src/air_properties.rs b/fastsim-core/src/air_properties.rs index 918a608f..a5030048 100644 --- a/fastsim-core/src/air_properties.rs +++ b/fastsim-core/src/air_properties.rs @@ -91,6 +91,7 @@ lazy_static! { )] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] pub struct Air {} impl Init for Air {} impl SerdeAPI for Air {} diff --git a/fastsim-core/src/drive_cycle.rs b/fastsim-core/src/drive_cycle.rs index 54aa7d6f..7bb54792 100644 --- a/fastsim-core/src/drive_cycle.rs +++ b/fastsim-core/src/drive_cycle.rs @@ -24,6 +24,7 @@ use fastsim_2::cycle::RustCycle as Cycle2; } )] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)] +#[non_exhaustive] /// Container pub struct Cycle { /// Name of cycle (can be left empty) @@ -402,6 +403,7 @@ impl Cycle { #[fastsim_api] #[derive(Default, Debug, Serialize, Deserialize, PartialEq, Clone)] +#[non_exhaustive] /// Element of `Cycle`. Used for vec-like operations. pub struct CycleElement { /// simulation time \[s\] diff --git a/fastsim-core/src/simdrive.rs b/fastsim-core/src/simdrive.rs index 4c3eb3dd..b2e6d0e5 100644 --- a/fastsim-core/src/simdrive.rs +++ b/fastsim-core/src/simdrive.rs @@ -7,6 +7,7 @@ use crate::prelude::*; #[fastsim_api] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Solver parameters pub struct SimParams { pub ach_speed_max_iter: u32, @@ -18,10 +19,6 @@ pub struct SimParams { pub trace_miss_opts: TraceMissOptions, /// whether to use FASTSim-2 style air density pub f2_air_density: bool, - // phantom private field to prevent direct instantiation in other modules - #[serde(skip)] - #[api(skip_get, skip_set)] - pub _phantom: PhantomData<()>, } impl SerdeAPI for SimParams {} @@ -36,7 +33,6 @@ impl Default for SimParams { trace_miss_tol: Default::default(), trace_miss_opts: Default::default(), f2_air_density: true, - _phantom: PhantomData, } } } @@ -72,15 +68,12 @@ impl Default for SimParams { )] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, HistoryMethods)] +#[non_exhaustive] pub struct SimDrive { #[has_state] pub veh: Vehicle, pub cyc: Cycle, pub sim_params: SimParams, - // phantom private field to prevent direct instantiation in other modules - #[serde(skip)] - #[api(skip_get, skip_set)] - _phantom: PhantomData<()>, } impl SerdeAPI for SimDrive {} @@ -101,7 +94,6 @@ impl SimDrive { veh, cyc, sim_params: sim_params.unwrap_or_default(), - _phantom: PhantomData, } } @@ -484,6 +476,7 @@ pwr deficit: {} kW } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, HistoryMethods)] +#[non_exhaustive] pub struct TraceMissTolerance { tol_dist: si::Length, tol_dist_frac: si::Ratio, diff --git a/fastsim-core/src/vehicle/bev.rs b/fastsim-core/src/vehicle/bev.rs index 36a34b37..c4de48e2 100644 --- a/fastsim-core/src/vehicle/bev.rs +++ b/fastsim-core/src/vehicle/bev.rs @@ -1,6 +1,7 @@ use super::*; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, HistoryMethods)] +#[non_exhaustive] /// Battery electric vehicle pub struct BatteryElectricVehicle { #[has_state] diff --git a/fastsim-core/src/vehicle/cabin.rs b/fastsim-core/src/vehicle/cabin.rs index 286a220f..d0a827aa 100644 --- a/fastsim-core/src/vehicle/cabin.rs +++ b/fastsim-core/src/vehicle/cabin.rs @@ -26,6 +26,7 @@ impl SerdeAPI for CabinOption {} #[fastsim_api] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Basic single thermal capacitance cabin thermal model, including HVAC /// system and controls pub struct SingleCapacitanceCabin { diff --git a/fastsim-core/src/vehicle/chassis.rs b/fastsim-core/src/vehicle/chassis.rs index 0c53c3f1..28468ea8 100755 --- a/fastsim-core/src/vehicle/chassis.rs +++ b/fastsim-core/src/vehicle/chassis.rs @@ -18,6 +18,7 @@ impl Init for DriveTypes {} #[fastsim_api] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize, HistoryMethods)] +#[non_exhaustive] /// Struct for simulating vehicle pub struct Chassis { /// Aerodynamic drag coefficient diff --git a/fastsim-core/src/vehicle/conv.rs b/fastsim-core/src/vehicle/conv.rs index ba355ed7..6deec86d 100644 --- a/fastsim-core/src/vehicle/conv.rs +++ b/fastsim-core/src/vehicle/conv.rs @@ -1,6 +1,7 @@ use super::*; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, HistoryMethods)] +#[non_exhaustive] /// Conventional vehicle with only a FuelConverter as a power source pub struct ConventionalVehicle { pub fs: FuelStorage, diff --git a/fastsim-core/src/vehicle/hev.rs b/fastsim-core/src/vehicle/hev.rs index f73d3b2b..a4086032 100644 --- a/fastsim-core/src/vehicle/hev.rs +++ b/fastsim-core/src/vehicle/hev.rs @@ -2,6 +2,7 @@ use super::{vehicle_model::VehicleState, *}; use crate::prelude::ElectricMachineState; #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, HistoryMethods)] +#[non_exhaustive] /// Hybrid vehicle with both engine and reversible energy storage (aka battery) /// This type of vehicle is not likely to be widely prevalent due to modularity of consists. pub struct HybridElectricVehicle { @@ -288,6 +289,7 @@ impl Mass for HybridElectricVehicle { #[fastsim_api] #[derive(Clone, Debug, Default, Deserialize, PartialEq)] +#[non_exhaustive] pub struct FCOnCauses(Vec); impl Init for FCOnCauses {} impl SerdeAPI for FCOnCauses {} @@ -309,6 +311,7 @@ impl FCOnCauses { // TODO: figure out why this is not turning in the dataframe but is in teh pydict #[fastsim_api] #[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)] +#[non_exhaustive] pub struct HEVState { /// time step index pub i: usize, @@ -381,6 +384,7 @@ impl fmt::Display for FCOnCause { /// Options for controlling simulation behavior #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[non_exhaustive] pub struct HEVSimulationParams { /// [ReversibleEnergyStorage] per [FuelConverter] pub res_per_fuel_lim: si::Ratio, @@ -555,6 +559,7 @@ impl HEVPowertrainControls { /// Container for static controls parameters. See [Self::init] for default /// values. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)] +#[non_exhaustive] pub struct RESGreedyWithDynamicBuffers { /// RES energy delta from minimum SOC corresponding to kinetic energy of /// vehicle at this speed that triggers ramp down in RES discharge. diff --git a/fastsim-core/src/vehicle/powertrain/electric_machine.rs b/fastsim-core/src/vehicle/powertrain/electric_machine.rs index a0e56431..897ca647 100755 --- a/fastsim-core/src/vehicle/powertrain/electric_machine.rs +++ b/fastsim-core/src/vehicle/powertrain/electric_machine.rs @@ -54,6 +54,7 @@ use crate::pyo3::*; // } )] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Struct for modeling electric machines. This lumps performance and efficiency of motor and power /// electronics. pub struct ElectricMachine { @@ -142,10 +143,12 @@ impl ElectricMachine { .eff_interp_at_max_input .as_ref() .map(|interpolator| { - interpolator.interpolate(&[abs_checked_x_val( - (pwr_in_fwd_lim / self.pwr_out_max).get::(), - interpolator.x().map_err(|e| anyhow!(e))?, - )?]).map_err(|e| anyhow!(e)) + interpolator + .interpolate(&[abs_checked_x_val( + (pwr_in_fwd_lim / self.pwr_out_max).get::(), + interpolator.x().map_err(|e| anyhow!(e))?, + )?]) + .map_err(|e| anyhow!(e)) }) .ok_or(anyhow!( "eff_interp_bwd is None, which should never be the case at this point." @@ -162,10 +165,12 @@ impl ElectricMachine { .eff_interp_at_max_input .as_ref() .map(|interpolator| { - interpolator.interpolate(&[abs_checked_x_val( - (pwr_in_bwd_lim / self.pwr_out_max).get::(), - interpolator.x().map_err(|e| anyhow!(e))?, - )?]).map_err(|e| anyhow!(e)) + interpolator + .interpolate(&[abs_checked_x_val( + (pwr_in_bwd_lim / self.pwr_out_max).get::(), + interpolator.x().map_err(|e| anyhow!(e))?, + )?]) + .map_err(|e| anyhow!(e)) }) .ok_or(anyhow!( "eff_interp_bwd is None, which should never be the case at this point." @@ -328,9 +333,7 @@ impl Init for ElectricMachine { self.eff_interp_fwd.strategy()?.to_owned(), self.eff_interp_fwd.extrapolate()?.to_owned(), )?; - self.eff_interp_at_max_input = Some(Interpolator::Interp1D( - eff_interp_at_max_input, - )); + self.eff_interp_at_max_input = Some(Interpolator::Interp1D(eff_interp_at_max_input)); } Ok(()) } @@ -447,7 +450,8 @@ impl ElectricMachine { .ok_or(anyhow!( "eff_interp_bwd is None, which should never be the case at this point." ))? - .f_x()?.to_owned(); + .f_x()? + .to_owned(); match &mut self.eff_interp_at_max_input { Some(Interpolator::Interp1D(interp1d)) => { // let old_interp = interp1d; @@ -628,6 +632,7 @@ impl ElectricMachine { #[derive( Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative, )] +#[non_exhaustive] pub struct ElectricMachineState { /// time step index pub i: usize, diff --git a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs index 8acf52c3..8fabdd2d 100755 --- a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs +++ b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs @@ -47,6 +47,7 @@ use super::*; } )] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Struct for modeling Fuel Converter (e.g. engine, fuel cell.) pub struct FuelConverter { /// [Self] Thermal plant, including thermal management controls @@ -87,10 +88,6 @@ pub struct FuelConverter { #[serde(default)] #[serde(skip_serializing_if = "FuelConverterStateHistoryVec::is_empty")] pub history: FuelConverterStateHistoryVec, - // phantom private field to prevent direct instantiation in other modules - #[serde(skip)] - #[api(skip_get, skip_set)] - pub(in super::super) _phantom: PhantomData<()>, } impl SetCumulative for FuelConverter { @@ -339,6 +336,7 @@ impl FuelConverter { #[derive( Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative, )] +#[non_exhaustive] pub struct FuelConverterState { /// time step index pub i: usize, @@ -395,6 +393,7 @@ impl SerdeAPI for FuelConverterThermalOption {} #[fastsim_api] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Struct for modeling Fuel Converter (e.g. engine, fuel cell.) pub struct FuelConverterThermal { /// [FuelConverter] thermal capacitance diff --git a/fastsim-core/src/vehicle/powertrain/fuel_storage.rs b/fastsim-core/src/vehicle/powertrain/fuel_storage.rs index fdd1b761..8f738fa2 100644 --- a/fastsim-core/src/vehicle/powertrain/fuel_storage.rs +++ b/fastsim-core/src/vehicle/powertrain/fuel_storage.rs @@ -14,6 +14,7 @@ use super::*; // } )] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq)] +#[non_exhaustive] pub struct FuelStorage { /// max power output pub pwr_out_max: si::Power, diff --git a/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs b/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs index 1f94c5dd..6c9a0179 100644 --- a/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs +++ b/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs @@ -74,6 +74,7 @@ const TOL: f64 = 1e-3; } )] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] /// Struct for modeling technology-naive Reversible Energy Storage (e.g. battery, flywheel). pub struct ReversibleEnergyStorage { /// ReversibleEnergyStorage mass @@ -568,6 +569,7 @@ pub enum SpecificEnergySideEffect { #[fastsim_api] #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)] +#[non_exhaustive] // component limits /// ReversibleEnergyStorage state variables pub struct ReversibleEnergyStorageState { diff --git a/fastsim-core/src/vehicle/powertrain/transmission.rs b/fastsim-core/src/vehicle/powertrain/transmission.rs index 3a40b0e6..bc1258b8 100644 --- a/fastsim-core/src/vehicle/powertrain/transmission.rs +++ b/fastsim-core/src/vehicle/powertrain/transmission.rs @@ -2,6 +2,7 @@ use super::*; #[fastsim_api] #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, HistoryMethods)] +#[non_exhaustive] pub struct Transmission { /// Transmission mass #[serde(default)] @@ -86,6 +87,7 @@ impl Mass for Transmission { #[fastsim_api] #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)] +#[non_exhaustive] pub struct TransmissionState { /// time step index pub i: usize, diff --git a/fastsim-core/src/vehicle/vehicle_model.rs b/fastsim-core/src/vehicle/vehicle_model.rs index 3303a469..401351fa 100644 --- a/fastsim-core/src/vehicle/vehicle_model.rs +++ b/fastsim-core/src/vehicle/vehicle_model.rs @@ -111,6 +111,7 @@ impl Init for AuxSource {} } )] #[derive(PartialEq, Clone, Debug, Serialize, Deserialize, HistoryMethods)] +#[non_exhaustive] /// Struct for simulating vehicle pub struct Vehicle { /// Vehicle name @@ -157,10 +158,6 @@ pub struct Vehicle { #[serde(default)] #[serde(skip_serializing_if = "VehicleStateHistoryVec::is_empty")] pub history: VehicleStateHistoryVec, - // phantom private field to prevent direct instantiation in other modules - #[serde(skip)] - #[api(skip_get, skip_set)] - _phantom: PhantomData<()>, } impl Mass for Vehicle { @@ -442,6 +439,7 @@ impl Vehicle { /// Vehicle state for current time step #[fastsim_api] #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, HistoryVec, SetCumulative)] +#[non_exhaustive] pub struct VehicleState { /// time step index pub i: usize, diff --git a/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs b/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs index 71ff3969..f17702ce 100644 --- a/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs +++ b/fastsim-core/src/vehicle/vehicle_model/fastsim2_interface.rs @@ -22,7 +22,6 @@ impl TryFrom for Vehicle { save_interval, history: Default::default(), mass: Some(f2veh.veh_kg * uc::KG), - _phantom: PhantomData, }; f3veh.expunge_mass_fields(); f3veh.init().with_context(|| anyhow!(format_dbg!()))?; @@ -76,7 +75,6 @@ impl TryFrom<&fastsim_2::vehicle::RustVehicle> for PowertrainType { pwr_idle_fuel: si::Power::ZERO, save_interval: Some(1), history: Default::default(), - _phantom: PhantomData, }; fc.init()?; fc.set_mass(None, MassSideEffect::None) @@ -149,7 +147,6 @@ impl TryFrom<&fastsim_2::vehicle::RustVehicle> for PowertrainType { pwr_idle_fuel: si::Power::ZERO, save_interval: Some(1), history: Default::default(), - _phantom: PhantomData, }; fc.init()?; fc.set_mass(None, MassSideEffect::None)