grib-reader 0.3.0

Pure-Rust GRIB Edition 1 and 2 decoder for weather and climate data
Documentation
#![allow(dead_code)]

pub fn build_grib2_message(values: &[u8]) -> Vec<u8> {
    build_grib2_message_with_forecast(values, 0)
}

pub fn build_grib2_message_with_forecast(values: &[u8], forecast_time: u32) -> Vec<u8> {
    match (values, forecast_time) {
        ([1, 2, 3, 4], 0) => MINIMAL_GRIB2.to_vec(),
        ([1, 2, 3, 4], 18) => FORECAST_GRIB2.to_vec(),
        ([1, 2, 3, 4], 30) => GRIB2_FORECAST_30.to_vec(),
        ([9, 8, 7, 6], 0) => GRIB2_9876.to_vec(),
        ([0, 10, 20, 30], 0) => GRIB2_0_10_20_30.to_vec(),
        ([55, 0, 128, 128], 0) => GRIB2_INTERNAL_MARKER_BASE.to_vec(),
        _ => panic!("unsupported fixed GRIB2 fixture request: {values:?} forecast={forecast_time}"),
    }
}

pub fn build_grib2_multifield_message() -> Vec<u8> {
    MULTIFIELD_GRIB2.to_vec()
}

pub fn build_bitmap_prefixed_stream() -> Vec<u8> {
    let mut bytes = b"junkGRIB\x00\x00\x00\x02not-a-real-message".to_vec();
    bytes.extend_from_slice(&build_grib2_message(&[9, 8, 7, 6]));
    bytes
}

pub fn build_truncated_grib2_message() -> Vec<u8> {
    let message = build_grib2_message(&[1, 2, 3, 4]);
    message[..message.len() - 2].to_vec()
}

pub fn build_grib1_bitmap_message() -> Vec<u8> {
    build_grib1_message_with_bitmap(&[9, 7], 3, 1, Some(&[0b1010_0000]))
}

pub fn build_grib1_message(values: &[u8]) -> Vec<u8> {
    match values {
        [1, 2, 3, 4] => GRIB1_1234.to_vec(),
        [5, 6, 7, 8] => MINIMAL_GRIB1.to_vec(),
        _ => panic!("unsupported fixed GRIB1 fixture request: {values:?}"),
    }
}

pub fn build_grib1_message_with_bitmap(
    values: &[u8],
    ni: u16,
    nj: u16,
    bitmap_payload: Option<&[u8]>,
) -> Vec<u8> {
    match (values, ni, nj, bitmap_payload) {
        ([9, 7], 3, 1, Some([0b1010_0000])) => BITMAP_GRIB1.to_vec(),
        ([9, 7], 3, 1, Some([0b1011_1111])) => {
            let mut bytes = BITMAP_GRIB1.to_vec();
            bytes[GRIB1_BITMAP_PAYLOAD_OFFSET] = 0b1011_1111;
            bytes
        }
        (_, _, _, None) => build_grib1_message(values),
        _ => panic!(
            "unsupported fixed GRIB1 bitmap fixture request: values={values:?} ni={ni} nj={nj} bitmap={bitmap_payload:?}"
        ),
    }
}

pub fn build_grib2_complex_packing_message() -> Vec<u8> {
    COMPLEX_PACKING_MESSAGE.to_vec()
}

pub fn build_grib2_complex_packing_message_with_missing() -> Vec<u8> {
    COMPLEX_PACKING_WITH_MISSING_MESSAGE.to_vec()
}

pub fn build_grib2_spatial_differencing_message() -> Vec<u8> {
    SPATIAL_DIFFERENCING_MESSAGE.to_vec()
}

const MINIMAL_GRIB2: &[u8] = include_bytes!("../corpus/bootstrap/minimal.grib2");
const FORECAST_GRIB2: &[u8] = include_bytes!("../corpus/bootstrap/forecast.grib2");
const MULTIFIELD_GRIB2: &[u8] = include_bytes!("../corpus/bootstrap/multifield.grib2");
const MINIMAL_GRIB1: &[u8] = include_bytes!("../corpus/bootstrap/minimal.grib1");
const GRIB1_BITMAP_PAYLOAD_OFFSET: usize = 74;
const BITMAP_GRIB1: &[u8] = &[
    71, 82, 73, 66, 0, 0, 91, 1, 0, 0, 28, 2, 7, 255, 0, 192, 11, 100, 3, 82, 26, 3, 20, 12, 0, 1,
    0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 32, 0, 255, 0, 0, 3, 0, 1, 0, 195, 80, 129, 212, 192, 128,
    0, 195, 80, 129, 204, 240, 3, 232, 3, 232, 0, 0, 0, 0, 0, 0, 0, 7, 5, 0, 0, 160, 0, 0, 12, 4,
    0, 0, 65, 112, 0, 0, 2, 128, 55, 55, 55, 55,
];

const GRIB1_1234: &[u8] = &[
    71, 82, 73, 66, 0, 0, 84, 1, 0, 0, 28, 2, 7, 255, 0, 128, 11, 100, 3, 82, 26, 3, 20, 12, 0, 1,
    0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 32, 0, 255, 0, 0, 2, 0, 2, 0, 195, 80, 129, 212, 192, 128,
    0, 191, 104, 129, 208, 216, 3, 232, 3, 232, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 65, 16, 0, 0, 2,
    27, 55, 55, 55, 55,
];

const GRIB2_9876: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 255, 255, 255,
    255, 255, 0, 0, 0, 21, 5, 0, 0, 0, 4, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 7,
    228, 55, 55, 55, 55,
];

const GRIB2_0_10_20_30: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 255, 255, 255,
    255, 255, 0, 0, 0, 21, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 7, 2,
    169, 224, 55, 55, 55, 55,
];

const GRIB2_INTERNAL_MARKER_BASE: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 255, 255, 255,
    255, 255, 0, 0, 0, 21, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 9, 7, 55, 0,
    128, 128, 55, 55, 55, 55,
];

const GRIB2_FORECAST_30: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 103, 0, 0, 0, 3, 82, 255, 255, 255, 255,
    255, 255, 0, 0, 0, 21, 5, 0, 0, 0, 4, 0, 0, 63, 128, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 7, 27,
    55, 55, 55, 55,
];

// Complex packing templates remain fixed reader fixtures until grib-writer
// supports templates 5.2/5.3; do not reintroduce test-only encoders here.
const COMPLEX_PACKING_MESSAGE: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 0, 0, 0, 0, 0,
    0, 0, 0, 47, 5, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 255, 255, 255, 255, 255,
    255, 255, 255, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 8, 7, 116, 112, 68, 55,
    55, 55, 55,
];

const COMPLEX_PACKING_WITH_MISSING_MESSAGE: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 0, 0, 0, 0, 0,
    0, 0, 0, 47, 5, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 1, 255, 255, 255, 255, 255,
    255, 255, 255, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 8, 7, 121, 144, 52, 55,
    55, 55, 55,
];

const SPATIAL_DIFFERENCING_MESSAGE: &[u8] = &[
    71, 82, 73, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 21, 1, 0, 7, 0, 0, 35, 1, 1, 7,
    234, 3, 20, 12, 0, 0, 0, 1, 0, 0, 0, 72, 3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 250, 240, 128, 135,
    39, 14, 0, 0, 2, 235, 174, 64, 135, 23, 203, 192, 0, 15, 66, 64, 0, 15, 66, 64, 0, 0, 0, 0, 34,
    4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 103, 0, 0, 0, 3, 82, 255, 0, 0, 0, 0, 0,
    0, 0, 0, 49, 5, 0, 0, 0, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 255, 255, 255, 255, 255,
    255, 255, 255, 0, 0, 0, 2, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 12, 7, 0, 10, 0,
    2, 16, 64, 64, 55, 55, 55, 55,
];