use std::fmt::Display;
use super::{custom_feature_format::CustomFeatureFormat, state_error::StateError};
use crate::model::{traversal::state::state_variable::StateVar, unit};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(untagged)]
pub enum StateFeature {
Distance {
distance_unit: unit::DistanceUnit,
initial: unit::Distance,
},
Time {
time_unit: unit::TimeUnit,
initial: unit::Time,
},
Energy {
energy_unit: unit::EnergyUnit,
initial: unit::Energy,
},
Custom {
name: String,
unit: String,
format: CustomFeatureFormat,
},
}
impl Display for StateFeature {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StateFeature::Distance {
distance_unit,
initial,
} => write!(f, "unit: {}, initial: {}", distance_unit, initial),
StateFeature::Time { time_unit, initial } => {
write!(f, "unit: {}, initial: {}", time_unit, initial)
}
StateFeature::Energy {
energy_unit,
initial,
} => write!(f, "unit: {}, initial: {}", energy_unit, initial),
StateFeature::Custom { name, unit, format } => {
write!(f, "name: {} unit: {}, repr: {}", name, unit, format)
}
}
}
}
impl StateFeature {
pub fn get_feature_name(&self) -> String {
match self {
StateFeature::Distance {
distance_unit: _,
initial: _,
} => String::from("distance"),
StateFeature::Time {
time_unit: _,
initial: _,
} => String::from("time"),
StateFeature::Energy {
energy_unit: _,
initial: _,
} => String::from("energy"),
StateFeature::Custom {
name,
unit: _,
format: _,
} => name.clone(),
}
}
pub fn get_feature_unit_name(&self) -> String {
match self {
StateFeature::Distance {
distance_unit,
initial: _,
} => distance_unit.to_string(),
StateFeature::Time {
time_unit,
initial: _,
} => time_unit.to_string(),
StateFeature::Energy {
energy_unit,
initial: _,
} => energy_unit.to_string(),
StateFeature::Custom {
name: _,
unit,
format: _,
} => unit.clone(),
}
}
pub fn get_feature_format(&self) -> CustomFeatureFormat {
match self {
StateFeature::Custom {
name: _,
unit: _,
format,
} => *format,
_ => CustomFeatureFormat::default(),
}
}
pub fn get_initial(&self) -> Result<StateVar, StateError> {
self.get_feature_format().initial()
}
pub fn get_distance_unit(&self) -> Result<unit::DistanceUnit, StateError> {
match self {
StateFeature::Distance {
distance_unit: unit,
initial: _,
} => Ok(*unit),
_ => Err(StateError::UnexpectedFeatureUnit(
String::from("distance"),
self.get_feature_name(),
)),
}
}
pub fn get_time_unit(&self) -> Result<unit::TimeUnit, StateError> {
match self {
StateFeature::Time {
time_unit: unit,
initial: _,
} => Ok(*unit),
_ => Err(StateError::UnexpectedFeatureUnit(
String::from("time"),
self.get_feature_name(),
)),
}
}
pub fn get_energy_unit(&self) -> Result<unit::EnergyUnit, StateError> {
match self {
StateFeature::Energy {
energy_unit,
initial: _,
} => Ok(*energy_unit),
_ => Err(StateError::UnexpectedFeatureUnit(
String::from("energy"),
self.get_feature_name(),
)),
}
}
pub fn get_custom_feature_format(&self) -> Result<&CustomFeatureFormat, StateError> {
match self {
StateFeature::Custom {
name: _,
unit: _,
format,
} => Ok(format),
_ => Err(StateError::UnexpectedFeatureUnit(
self.get_feature_unit_name(),
self.get_feature_name(),
)),
}
}
}