use std::borrow::Cow;
use crate::model::{
state::{StateModel, StateModelError, StateVariable},
traversal::default::fieldname,
unit::{AsF64, Convert, Distance, DistanceUnit, Grade, GradeUnit, UnitError},
};
#[derive(Clone, Debug)]
pub struct ElevationChange {
elevation: Distance,
distance_unit: DistanceUnit,
}
impl ElevationChange {
pub fn new(
distance: (&Distance, &DistanceUnit),
grade: (&Grade, &GradeUnit),
) -> Result<ElevationChange, UnitError> {
let (d, du) = distance;
let (g, gu) = grade;
let mut g_dec = Cow::Borrowed(g);
gu.convert(&mut g_dec, &GradeUnit::Decimal)?;
let elevation = Distance::from(g_dec.as_f64() * d.as_f64());
Ok(ElevationChange {
elevation,
distance_unit: *du,
})
}
pub fn add_elevation_to_state(
&self,
state: &mut [StateVariable],
state_model: &StateModel,
) -> Result<(), StateModelError> {
if self.elevation == Distance::ZERO {
return Ok(());
}
let feature_name = if self.elevation < Distance::ZERO {
fieldname::TRIP_ELEVATION_LOSS
} else {
fieldname::TRIP_ELEVATION_GAIN
};
state_model.add_distance(state, feature_name, &self.elevation, &self.distance_unit)
}
}