grib-reader 0.1.2

Pure-Rust GRIB Edition 1 and 2 decoder for weather and climate data
Documentation

grib-rust

Pure-Rust, read-only GRIB decoder for weather and climate data. No C libraries, no build scripts, and no unsafe beyond memmap2.

Crates

Crate Description
grib-reader GRIB1/GRIB2 field scanning, metadata parsing, and packed data decoding

Usage

use grib_reader::GribFile;

let file = GribFile::open("gfs.grib2")?;
println!("messages: {}", file.message_count());

for msg in file.messages() {
    println!(
        "  {} {:?} {:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
        msg.parameter_name(),
        msg.grid_shape(),
        msg.reference_time().year,
        msg.reference_time().month,
        msg.reference_time().day,
        msg.reference_time().hour,
        msg.reference_time().minute,
        msg.reference_time().second,
    );

    if let Some(valid) = msg.valid_time() {
        println!(
            "  valid {:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
            valid.year,
            valid.month,
            valid.day,
            valid.hour,
            valid.minute,
            valid.second,
        );
    }
}

let field = file.message(0)?;
let flat = field.read_flat_data_as_f64()?;
println!("decoded values: {}", flat.len());

let data = field.read_data_as_f64()?;
println!("ndarray shape: {:?}", data.shape());

let tolerant = GribFile::from_bytes_with_options(
    std::fs::read("mixed.bin")?,
    grib_reader::OpenOptions { strict: false },
)?;
println!("recoverable messages: {}", tolerant.message_count());

Supported Now

  • GRIB1 and GRIB2 message scanning with "GRIB"/"7777" boundary detection
  • Logical field indexing for multi-field GRIB2 messages
  • Regular latitude/longitude grids for GRIB1 and GRIB2
  • Simple packing for GRIB1 and GRIB2
  • WMO parameter table lookups (Code Table 4.2)
  • Typed metadata access for reference time, parameter identity, product metadata, grid geometry, and lat/lon coordinates
  • Forecast valid-time helpers from reference time + lead time
  • OpenOptions for strict or tolerant scanning
  • Bitmap application with missing values surfaced as NaN
  • Parallel field decoding via Rayon
  • Output: flat Vec<f64> or ndarray::ArrayD<f64>
  • Memory-mapped I/O or owned byte buffers

Not Yet Supported

  • Non-lat/lon grid templates
  • Complex packing and more advanced multi-packing templates
  • JPEG2000 and PNG-packed GRIB2 fields
  • GRIB1 predefined bitmaps

Unsupported cases fail explicitly with typed errors.

Feature flags

Flag Default Description
rayon yes Parallel field decoding

Testing

cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo run -p grib-reader --example sync_corpus
git diff --exit-code
cargo test --all-features
cargo test --no-default-features
cargo check --manifest-path grib-reader/fuzz/Cargo.toml --bins
cargo clippy --manifest-path grib-reader/fuzz/Cargo.toml --bins -- -D warnings

Reference compatibility checks are intentionally outside default PR CI:

./scripts/run-reference-parity.sh

Release Checklist

git switch main
git pull --ff-only
git merge <release-branch>

cargo package -p grib-reader
cargo publish -p grib-reader

git tag v<version>
git push origin main
git push origin v<version>

Corpus And Fuzzing

  • Bootstrap corpus samples live in grib-reader/tests/corpus/bootstrap/
  • Real interoperability samples belong in grib-reader/tests/corpus/interop/samples/
  • Regenerate the bootstrap and fuzz seed corpora with cargo run -p grib-reader --example sync_corpus
  • Fuzzer entry points and usage notes live in grib-reader/fuzz/README.md

Reference Checks

  • ./scripts/run-reference-parity.sh runs the Dockerized ecCodes parity suite.
  • For reference comparisons and current benchmark results against ecCodes, see docs/benchmark-report.md.

License

MIT OR Apache-2.0