gribberish 0.30.3

Parse grib 2 files with Rust
Documentation
use super::grib_section::GribSection;
use crate::utils::{read_u16_from_bytes, read_u32_from_bytes};
use chrono::prelude::*;
use gribberish_macros::{DisplayDescription, FromValue};

#[repr(u8)]
#[derive(Eq, PartialEq, Debug, DisplayDescription, FromValue)]
pub enum ReferenceDataSignificance {
    Analysis = 0,
    #[description = "start of forecast"]
    StartOfForecast = 1,
    #[description = "verifying time of forecast"]
    VerifyingTimeOfForecast = 2,
    #[description = "observation time"]
    ObservationTime = 3,
    Missing = 255,
}

#[repr(u8)]
#[derive(Eq, PartialEq, Debug, DisplayDescription, FromValue)]
pub enum ProductionStatus {
    Operational = 0,
    #[description = "operational test"]
    OperationalTest = 1,
    Research = 2,
    ReAnalysis = 3,
    #[description = "TIGGE"]
    TIGGE = 4,
    #[description = "TIGGE test"]
    TIGGETest = 5,
    #[description = "s2s operational"]
    S2SOperational = 6,
    #[description = "s2s test"]
    S2STest = 7,
    #[description = "UERRA"]
    UERRA = 8,
    #[description = "UERRA test"]
    UERRATest = 9,
    Missing = 255,
}

#[repr(u8)]
#[derive(Eq, PartialEq, Debug, DisplayDescription, FromValue)]
pub enum GribDataType {
    Analysis = 0,
    Forecast = 1,
    #[description = "analysis and forecast"]
    AnalysisAndForecast = 2,
    #[description = "control forecast"]
    ControlForecast = 3,
    #[description = "perturbed forecast"]
    PerturbedForecast = 4,
    #[description = "control and perturbed forecast"]
    ControlAndPerturbedForecast = 5,
    #[description = "processed satellite observations"]
    ProcessedSatelliteObservations = 6,
    #[description = "processed radar observations"]
    ProcessedRadarObservations = 7,
    #[description = "event probability"]
    EventProbability = 8,
    Experimental = 192,
    Missing = 255,
}

pub struct IdentificationSection<'a> {
    data: &'a [u8],
}

impl<'a> IdentificationSection<'a> {
    pub fn from_data(data: &'a [u8]) -> Self {
        IdentificationSection { data }
    }

    pub fn reference_date_significance(&self) -> ReferenceDataSignificance {
        self.data[11].into()
    }

    pub fn reference_date(&self) -> DateTime<Utc> {
        let year = read_u16_from_bytes(self.data, 12).unwrap_or(0) as i32;
        let month = self.data[14] as u32;
        let day = self.data[15] as u32;
        let hour = self.data[16] as u32;
        let minute = self.data[17] as u32;
        let second = self.data[18] as u32;

        Utc.with_ymd_and_hms(year, month, day, hour, minute, second)
            .unwrap()
    }

    pub fn production_status(&self) -> ProductionStatus {
        self.data[19].into()
    }

    pub fn data_type(&self) -> GribDataType {
        self.data[20].into()
    }
}

impl<'a> GribSection for IdentificationSection<'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]
    }
}