gribberish 0.28.0

Parse grib 2 files with Rust
Documentation
use std::str;
use gribberish_macros::{DisplayDescription, FromValue};
use crate::utils::read_u64_from_bytes;
use super::grib_section::GribSection;

fn validate_indicator_section(data: &[u8]) -> bool {
	match str::from_utf8(&data[0..4]) {
		Ok(s) => s == "GRIB",
		_ => false
	}
}

#[repr(u8)]
#[derive(Eq, Clone, PartialEq, Debug, DisplayDescription, FromValue)]
pub enum Discipline {
	Meteorological = 0,
	Hydrological = 1,
	LandSurface = 2,
	Space = 3,
	Oceanographic = 10,
	MultiRadarMultiSensor = 209,
	Missing = 255,
}

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

impl <'a> IndicatorSection<'a> {

	pub fn from_data(data: &'a [u8]) -> Self {
		IndicatorSection {
            data,
		}
	}

    pub fn is_indicator_section(data: &[u8], offset: usize) -> bool {
        validate_indicator_section(&data[offset..offset+4])
    }

	pub fn valid(&self) -> bool {
        validate_indicator_section(&self.data[0..4])
    }

	pub fn discipline_value(&self) -> u8 {
		self.data[6]
	}

	pub fn discipline(&self) -> Discipline {
		self.data[6].into()
	}

	pub fn edition(&self) -> u8 {
		self.data[7]
	}

	pub fn total_length(&self) -> u64 {
		read_u64_from_bytes(self.data, 8).unwrap_or(0) as u64
	}
}

impl <'a> GribSection for IndicatorSection<'a> {
    fn len(&self) -> usize {
        16
    }

    fn number(&self) -> u8 {
        0
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn read_indicator() {
		use super::{IndicatorSection, Discipline};

		let raw = [0x47u8, 0x52, 0x49, 0x42, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3];
		let indicator = IndicatorSection::from_data(&raw);
        assert!(indicator.valid());
		assert!(indicator.discipline() == Discipline::Meteorological);
	}
}