Skip to main content

oxigdal_grib/
lib.rs

1//! OxiGDAL GRIB Driver - Pure Rust GRIB1/GRIB2 Meteorological Data Format Support
2//!
3//! This crate provides comprehensive support for reading GRIB (GRIdded Binary) format files,
4//! which are commonly used for meteorological and climate data. Both GRIB Edition 1 and
5//! GRIB Edition 2 formats are supported.
6//!
7//! # Features
8//!
9//! - **Pure Rust Implementation**: No C/Fortran dependencies, fully compliant with COOLJAPAN policies
10//! - **GRIB1 and GRIB2 Support**: Read both legacy and modern GRIB formats
11//! - **Parameter Tables**: WMO standard parameter lookups for meteorological variables
12//! - **Grid Definitions**: Support for regular lat/lon, Lambert conformal, Mercator, polar stereographic
13//! - **Data Decoding**: Efficient unpacking of packed binary data with proper scaling
14//! - **Integration**: Designed to integrate seamlessly with oxigdal-core Dataset
15//!
16//! # Quick Start
17//!
18//! ```no_run
19//! use oxigdal_grib::reader::GribReader;
20//!
21//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
22//! // Open a GRIB file
23//! let mut reader = GribReader::open("data/forecast.grib2")?;
24//!
25//! // Read all messages
26//! for record in reader {
27//!     let record = record?;
28//!
29//!     // Get parameter information
30//!     let param = record.parameter()?;
31//!     println!("Parameter: {} ({})", param.long_name, param.units);
32//!
33//!     // Get level information
34//!     println!("Level: {:?} = {}", record.level_type(), record.level_value());
35//!
36//!     // Decode data
37//!     let data = record.decode_data()?;
38//!     println!("Data points: {}", data.len());
39//! }
40//! # Ok(())
41//! # }
42//! ```
43//!
44//! # GRIB Format Overview
45//!
46//! GRIB (GRIdded Binary) is a concise data format commonly used in meteorology for storing
47//! historical and forecast weather data. It is standardized by the World Meteorological
48//! Organization (WMO).
49//!
50//! ## GRIB1 Structure
51//!
52//! - Indicator Section (IS): Magic bytes 'GRIB' and edition number
53//! - Product Definition Section (PDS): Metadata about the parameter, level, time
54//! - Grid Definition Section (GDS): Grid geometry and projection
55//! - Bit Map Section (BMS): Optional bitmap for missing values
56//! - Binary Data Section (BDS): Packed binary data
57//! - End Section: Magic bytes '7777'
58//!
59//! ## GRIB2 Structure
60//!
61//! - Section 0: Indicator Section
62//! - Section 1: Identification Section
63//! - Section 2: Local Use Section (optional)
64//! - Section 3: Grid Definition Section
65//! - Section 4: Product Definition Section
66//! - Section 5: Data Representation Section
67//! - Section 6: Bit-Map Section (optional)
68//! - Section 7: Data Section
69//! - Section 8: End Section
70//!
71//! # Architecture
72//!
73//! The crate is organized into several modules:
74//!
75//! - [`error`]: Error types for GRIB operations
76//! - [`message`]: Core message parsing and iteration
77//! - [`parameter`]: WMO parameter tables and lookups
78//! - [`grid`]: Grid definitions and coordinate systems
79//! - [`grib1`]: GRIB Edition 1 format support
80//! - [`grib2`]: GRIB Edition 2 format support
81//! - [`reader`]: High-level file reading API
82//!
83//! # Performance
84//!
85//! This implementation focuses on correctness and simplicity while maintaining reasonable
86//! performance. For production use with large GRIB files, consider:
87//!
88//! - Using buffered I/O (automatically done with `GribReader::open`)
89//! - Processing messages in parallel when appropriate
90//! - Caching decoded data if the same message is accessed multiple times
91
92#![cfg_attr(not(feature = "std"), no_std)]
93#![warn(missing_docs)]
94#![warn(rustdoc::missing_crate_level_docs)]
95
96#[cfg(not(feature = "std"))]
97extern crate alloc;
98
99pub mod error;
100pub mod grid;
101pub mod message;
102pub mod parameter;
103pub mod reader;
104pub mod templates;
105
106#[cfg(feature = "grib1")]
107pub mod grib1;
108
109#[cfg(feature = "grib2")]
110pub mod grib2;
111
112// Re-exports for convenience
113pub use error::{GribError, Result};
114pub use grid::GridDefinition;
115pub use message::{GribEdition, GribMessage};
116pub use parameter::{LevelType, Parameter};
117pub use reader::{GribReader, GribRecord};
118
119/// Crate version
120pub const VERSION: &str = env!("CARGO_PKG_VERSION");
121
122/// Check if GRIB1 support is enabled
123pub const fn has_grib1_support() -> bool {
124    cfg!(feature = "grib1")
125}
126
127/// Check if GRIB2 support is enabled
128pub const fn has_grib2_support() -> bool {
129    cfg!(feature = "grib2")
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_version() {
138        assert!(!VERSION.is_empty());
139    }
140
141    #[test]
142    fn test_feature_flags() {
143        // Both should be enabled by default
144        assert!(has_grib1_support());
145        assert!(has_grib2_support());
146    }
147}