gribberish 1.1.1

Parse grib 2 files with Rust
Documentation
use super::grib_section::GribSection;
use crate::{
    templates::product::{
        derived_ensemble_forecast_time_interval_reference_template::DerivedEnsembleForecastTimeIntervalReferenceTemplate,
        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,
                ),
            )),
            107 => Some(Box::new(
                DerivedEnsembleForecastTimeIntervalReferenceTemplate::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]
    }
}