use crate::measurements::Speed;
use crate::{FuelFlow, VerticalDistance};
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct PerformanceTableRow {
pub level: VerticalDistance,
pub tas: Speed,
pub ff: FuelFlow,
}
pub type PerformanceTable = Vec<PerformanceTableRow>;
#[derive(Clone, Eq, PartialEq, Debug, Default)]
pub struct Performance {
table: PerformanceTable,
}
impl Performance {
pub fn new(table: PerformanceTable) -> Self {
Self { table }
}
pub fn from_fn<F>(f: F, ceiling: VerticalDistance) -> Self
where
F: Fn(&VerticalDistance) -> (Speed, FuelFlow),
{
let mut table: PerformanceTable = Vec::new();
let mut vd = VerticalDistance::Gnd;
let mut alt = 0;
while vd <= ceiling {
let (tas, ff) = f(&vd);
table.push(PerformanceTableRow { level: vd, tas, ff });
alt += 1000;
vd = VerticalDistance::Altitude(alt);
}
Self { table }
}
pub fn tas(&self, level: &VerticalDistance) -> Speed {
self.at_level(level).tas
}
pub fn ff(&self, level: &VerticalDistance) -> FuelFlow {
self.at_level(level).ff
}
fn at_level(&self, level: &VerticalDistance) -> &PerformanceTableRow {
self.table
.iter()
.rfind(|row| &row.level <= level)
.expect("There should be at least one row in the table.")
}
}