Rust bindings#87
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #87 +/- ##
========================================
Coverage 74.89% 74.89%
========================================
Files 98 98
Lines 5047 5047
Branches 445 445
========================================
Hits 3780 3780
Misses 1267 1267 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces Rust bindings for the ECMWF gribjump C++ library, including a low-level gribjump-sys FFI layer and a safe gribjump wrapper crate, plus supporting tests/fixtures, examples, and benchmarks.
Changes:
- Add
gribjump-sys(cxx bridge + build script) to build/link gribjump (vendored or system). - Add
gribjumpsafe wrapper API (handle, requests, iterator, results, error mapping). - Add integration/thread-safety/async tests, fixtures, examples, and Rust/C++ benchmarks.
Reviewed changes
Copilot reviewed 27 out of 32 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| rust/crates/gribjump/tests/gribjump_thread_safety.rs | Thread-safety + concurrency tests (ignored runtime cases) |
| rust/crates/gribjump/tests/gribjump_integration.rs | Integration tests that set up an FDB and validate wrapper behavior |
| rust/crates/gribjump/tests/gribjump_async.rs | Tokio-based concurrent access tests (ignored by default) |
| rust/crates/gribjump/tests/fixtures/template.grib | Added GRIB fixture |
| rust/crates/gribjump/tests/fixtures/synth11.grib | Added GRIB fixture used for tests/benches |
| rust/crates/gribjump/tests/fixtures/schema | Added FDB schema fixture |
| rust/crates/gribjump/tests/fixtures/extract_ranges.grib | Added GRIB fixture for range extraction tests |
| rust/crates/gribjump/tests/fixtures/axes.grib | Added GRIB fixture for axes tests |
| rust/crates/gribjump/src/result.rs | Zero-copy result types + views + owned conversions |
| rust/crates/gribjump/src/request.rs | Request/range types and conversion to FFI types |
| rust/crates/gribjump/src/lib.rs | Crate module wiring + public re-exports |
| rust/crates/gribjump/src/iterator.rs | Iterator wrapper over FFI extraction iterator |
| rust/crates/gribjump/src/handle.rs | Thread-safe handle wrapper around the FFI handle |
| rust/crates/gribjump/src/error.rs | Rust error type + mapping from cxx::Exception |
| rust/crates/gribjump/examples/gribjump_file.rs | Example: scan + extract from file offsets |
| rust/crates/gribjump/examples/gribjump_extract.rs | Example: build request + extract ranges |
| rust/crates/gribjump/examples/gribjump_basic.rs | Example: version/git-sha + handle creation |
| rust/crates/gribjump/examples/gribjump_axes.rs | Example: axes query |
| rust/crates/gribjump/benches/gribjump_bench.rs | Criterion benchmarks for Rust wrapper |
| rust/crates/gribjump/benches/cpp/gribjump_bench.cpp | Google Benchmark comparison using native C++ API |
| rust/crates/gribjump/benches/cpp/CMakeLists.txt | CMake build for C++ benchmarks |
| rust/crates/gribjump/README.md | Wrapper crate documentation |
| rust/crates/gribjump/Cargo.toml | Wrapper crate manifest |
| rust/crates/gribjump-sys/src/lib.rs | cxx::bridge definitions for FFI API surface |
| rust/crates/gribjump-sys/cpp/gribjump_bridge.h | C++ bridge declarations + global try/catch mapping |
| rust/crates/gribjump-sys/cpp/gribjump_bridge.cpp | C++ bridge implementation + conversions + validations |
| rust/crates/gribjump-sys/build.rs | Vendored/system build + link configuration for the bridge |
| rust/crates/gribjump-sys/README.md | Sys crate documentation |
| rust/crates/gribjump-sys/Cargo.toml | Sys crate manifest + features |
| rust/Cargo.toml | Rust workspace definition + shared deps |
| .gitignore | Ignore Rust build artifacts/lockfile under rust/ |
| .github/workflows/rust.yml.example | Example CI workflow for Rust checks/tests/fmt/clippy |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mathleur
left a comment
There was a problem hiding this comment.
Looks good to me, I just had one question/comment about the PathExtractionRequest constructor, which we might start using in Polytope in the future
|
Hi @Choochmeque, just so you are aware there is a PR likely to be merged soon which cleans up of the gribjump source code. This involved moving and renaming some API headers, so will likely affect your work. It should be fairly easy to update the relevant paths in your implementation, but just letting you know in advance. |
Hi @ChrisspyB, |
| gribjump = { path = "crates/gribjump" } | ||
|
|
||
| # FDB dependency | ||
| fdb = { git = "ssh://git@github.com/ecmwf/fdb.git", branch = "rust-bindings", default-features = false } |
There was a problem hiding this comment.
Reminder note to switch this away from rust-bindings.
| #[derive(Debug, Clone, Default)] | ||
| pub struct ExtractionRequestData { | ||
| /// MARS request string (e.g., "class=od,expver=0001,...") | ||
| pub request_str: String, |
There was a problem hiding this comment.
Placeholder note - this really ought to be a MarsRequest. Although it looks like gribjump is lagging there...
| #[cfg(feature = "system")] | ||
| #[allow(clippy::too_many_lines)] | ||
| fn cmake_find_package( | ||
| package: &str, |
There was a problem hiding this comment.
Is this code that is going to need to be duplicated in all packages?
There was a problem hiding this comment.
Fixed via bindman-build crate.
5e82044 to
c836cd8
Compare
|
Please rebase on the latest develop, all (py)gribjump tests should now pass the CI |
… gribjump_bridge.h
…xample, because it should be reusable-action)
…ount and success
This reverts commit d320a22.
7700a36 to
70e3b41
Compare
All green now. Thanks! |
simondsmart
left a comment
There was a problem hiding this comment.
Some comments that should be addressed. But fundamentally happy.
I would like some clarification about the Range question, but otherwise ready to merge when you are (re the comments)
|
|
||
| // Set FDB5_CONFIG for GribJump | ||
| unsafe { | ||
| env::set_var("FDB5_CONFIG", &config); |
There was a problem hiding this comment.
This still feels like it is in the wrong place relative to a function called setup_test_dir. Feels like hidden, magic, implicit behaviour. That were are (re)setting the env var needs to be made clear in the naming, or moved out to the calling function, or something.
| assert!(results.iter().all(|(_, c)| *c == first_count)); | ||
| println!("Concurrent axes: all tasks found {first_count} axis entries"); | ||
|
|
||
| drop(gj); |
There was a problem hiding this comment.
Unclear why the explicit drop calls are needed? This seems to be the natural drop order implied by the construction order?
|
|
||
| /// A range of indices to extract (start and end inclusive). | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] | ||
| pub struct Range { |
There was a problem hiding this comment.
Is there a reason we can't use std::Range here? Seems to carry the same functionality.
There was a problem hiding this comment.
- Validation - Range::new() rejects empty ranges at construction; std::ops::Range allows 5..3 silently
- Copy - our Range is Copy; std::ops::Range is not (because it implements Iterator)
- No clippy conflicts - vec![Range::new(0, 100)?] is unambiguous; vec![0..100] triggers single_range_in_vec_init
- Interop - From<std::ops::Range> lets users write (0..100).into() when they want standard syntax (added in da0883d)
|
|
||
| /// Get the gribjump library version. | ||
| #[must_use] | ||
| pub fn version() -> String { |
There was a problem hiding this comment.
I'm not sure that the version/git_sha1 functions belong to the GribJump struct.
They certainly belong somewhere in the crate (they are library-level info). But Not sure that they should be part of the object.
…sts for GribJump cloning functionality.
…h exclusive end behavior
Description
Contributor Declaration
By opening this pull request, I affirm the following: