use super::grib_section::GribSection;
use crate::{
templates::product::{
derived_ensemble_horizontal_forecast_time_interval_template::DerivedEnsembleHorizontalForecastTimeIntervalTemplate,
product_template::ProductTemplate,
AverageAccumulationExtremeHorizontalAnalysisForecastTemplate,
DerivedEnsembleHorizontalAnalysisForecastTemplate, EnsembleForecastTimeIntervalTemplate,
HorizontalAnalysisForecastTemplate, HorizontalEnsembleForecastTemplate,
PercentileHorizontalTimeIntervalTemplate, ProbabilityHorizontalForecastTemplate,
ProbabilityHorizontalTimeIntervalTemplate,
},
utils::{read_u16_from_bytes, read_u32_from_bytes},
};
pub struct ProductDefinitionSection<'a> {
data: &'a [u8],
}
impl<'a> ProductDefinitionSection<'a> {
pub fn from_data(data: &'a [u8]) -> Self {
ProductDefinitionSection { data }
}
pub fn coord_values_after_template(&self) -> u16 {
read_u16_from_bytes(self.data, 5).unwrap_or(0)
}
pub fn product_definition_template_number(&self) -> u16 {
read_u16_from_bytes(self.data, 7).unwrap_or(0)
}
pub fn product_definition_template(&self, discipline: u8) -> Option<Box<dyn ProductTemplate>> {
match self.product_definition_template_number() {
0 => Some(Box::new(HorizontalAnalysisForecastTemplate::new(
self.data.to_vec(),
discipline,
))),
1 => Some(Box::new(HorizontalEnsembleForecastTemplate::new(
self.data.to_vec(),
discipline,
))),
2 => Some(Box::new(
DerivedEnsembleHorizontalAnalysisForecastTemplate::new(
self.data.to_vec(),
discipline,
),
)),
8 => Some(Box::new(
AverageAccumulationExtremeHorizontalAnalysisForecastTemplate::new(
self.data.to_vec(),
discipline,
),
)),
5 => Some(Box::new(ProbabilityHorizontalForecastTemplate::new(
self.data.to_vec(),
discipline,
))),
9 => Some(Box::new(ProbabilityHorizontalTimeIntervalTemplate::new(
self.data.to_vec(),
discipline,
))),
10 => Some(Box::new(PercentileHorizontalTimeIntervalTemplate::new(
self.data.to_vec(),
discipline,
))),
11 => Some(Box::new(EnsembleForecastTimeIntervalTemplate::new(
self.data.to_vec(),
discipline,
))),
12 => Some(Box::new(
DerivedEnsembleHorizontalForecastTimeIntervalTemplate::new(
self.data.to_vec(),
discipline,
),
)),
_ => None,
}
}
}
impl<'a> GribSection for ProductDefinitionSection<'a> {
fn len(&self) -> usize {
read_u32_from_bytes(&self.data[0..4], 0).unwrap_or(0) as usize
}
fn number(&self) -> u8 {
self.data[4]
}
}