Struct eccodes::codes_handle::CodesHandle
source · pub struct CodesHandle<SOURCE: Debug + SpecialDrop> { /* private fields */ }
Expand description
Structure providing access to the GRIB file which takes a full ownership of the accessed file.
It can be constructed from:
- File path using
new_from_file()
- From memory buffer using
new_from_memory()
- From GRIB index using
new_from_index()
(withexperimental_index
feature enabled)
Destructor for this structure does not panic, but some internal functions may rarely fail
leading to bugs. Errors encountered in the destructor are logged with log
.
§FallibleStreamingIterator
This structure implements FallibleStreamingIterator
trait which allows to access GRIB messages.
To access GRIB messages the ecCodes library uses a method similar to a C-style iterator.
It digests the * FILE
multiple times, each time returning the *mut codes_handle
to a message inside the file. The behavior of previous *mut codes_handle
after next one is generated is undefined
and we assume here that it is unsafe to use “old” *mut codes_handle
.
In Rust, such pattern is best represented by a streaming iterator which returns a reference to the message,
that is valid only until the next iteration. If you need to prolong the lifetime of the message, you can clone it.
Internal ecCodes functions can fail, necessitating the streaming iterator to be implemented with
FallibleStreamingIterator
trait.
As of 0.10
release, none of the available streaming iterator crates utilises already stabilized GATs.
This unfortunately significantly limits the number of methods available for CodesHandle
iterator.
Therefore the probably most versatile way to iterate over the messages is to use while let
loop.
use eccodes::{ProductKind, CodesHandle, KeyType};
// FallibleStreamingIterator must be in scope to use it
use eccodes::FallibleStreamingIterator;
let file_path = Path::new("./data/iceland-surface.grib");
let product_kind = ProductKind::GRIB;
let mut handle = CodesHandle::new_from_file(file_path, product_kind)?;
// Print names of messages in the file
while let Some(message) = handle.next()? {
// The message must be unwraped as internal next() can fail
let key = message.read_key("name")?;
if let KeyType::Str(name) = key.value {
println!("{:?}", name);
}
}
You can also manually collect the messages into a vector to use them later.
use eccodes::{ProductKind, CodesHandle, KeyedMessage};
use eccodes::FallibleStreamingIterator;
let file_path = Path::new("./data/iceland-surface.grib");
let product_kind = ProductKind::GRIB;
let mut handle = CodesHandle::new_from_file(file_path, product_kind)?;
let mut handle_collected = vec![];
while let Some(msg) = handle.next()? {
handle_collected.push(msg.try_clone()?);
}
All available methods for CodesHandle
iterator can be found in FallibleStreamingIterator
trait.
Implementations§
source§impl CodesHandle<GribFile>
impl CodesHandle<GribFile>
sourcepub fn new_from_file(
file_path: &Path,
product_kind: ProductKind
) -> Result<Self, CodesError>
pub fn new_from_file( file_path: &Path, product_kind: ProductKind ) -> Result<Self, CodesError>
Opens file at given Path
as selected ProductKind
and contructs CodesHandle
.
§Example
let file_path = Path::new("./data/iceland.grib");
let product_kind = ProductKind::GRIB;
let handle = CodesHandle::new_from_file(file_path, product_kind)?;
The function creates fs::File
from provided path and utilises
fdopen()
to associate io::RawFd
with a stream represented by libc::FILE
pointer.
The constructor takes as argument a path
instead of File
to ensure that fdopen()
uses the same mode as File
.
The file stream and File
are safely closed when CodesHandle
is dropped.
§Errors
Returns CodesError::FileHandlingInterrupted
with io::Error
when the file cannot be opened.
Returns CodesError::LibcNonZero
with errno
information
when the stream cannot be created from the file descriptor.
Returns CodesError::Internal
with error code
when internal codes_handle
cannot be created.
sourcepub fn new_from_memory(
file_data: Bytes,
product_kind: ProductKind
) -> Result<Self, CodesError>
pub fn new_from_memory( file_data: Bytes, product_kind: ProductKind ) -> Result<Self, CodesError>
Opens data in provided Bytes
buffer as selected ProductKind
and contructs CodesHandle
.
§Example
let product_kind = ProductKind::GRIB;
let file_data =
reqwest::get("https://github.com/ScaleWeather/eccodes/blob/main/data/iceland.grib?raw=true")
.await?
.bytes()
.await?;
let handle = CodesHandle::new_from_memory(file_data, product_kind)?;
The function associates data in memory with a stream
represented by libc::FILE
pointer
using fmemopen()
.
The constructor takes full ownership of the data inside Bytes
,
which is safely dropped during the CodesHandle
drop.
§Errors
Returns CodesError::LibcNonZero
with errno
information
when the file stream cannot be created.
Returns CodesError::Internal
with error code
when internal codes_handle
cannot be created.
source§impl CodesHandle<CodesIndex>
impl CodesHandle<CodesIndex>
sourcepub fn new_from_index(index: CodesIndex) -> Result<Self, CodesError>
Available on crate feature experimental_index
only.
pub fn new_from_index(index: CodesIndex) -> Result<Self, CodesError>
experimental_index
only.Creates CodesHandle
for provided CodesIndex
.
§Example
let index = CodesIndex::new_from_keys(&vec!["shortName", "typeOfLevel", "level"])?;
let handle = CodesHandle::new_from_index(index)?;
Ok(())
The function takes ownership of the provided CodesIndex
which owns
the GRIB data. CodesHandle
created from CodesIndex
is of different type
than the one created from file or memory buffer, because it internally uses
different functions to access messages. But it can be used in the same way.
⚠️ Warning: This function may interfere with other functions in concurrent context,
due to ecCodes issues with thread-safety for indexes. More information can be found
in codes_index
module documentation.
§Errors
Returns CodesError::Internal
with error code
when internal codes_handle
cannot be created.
Trait Implementations§
source§impl FallibleStreamingIterator for CodesHandle<CodesIndex>
Available on crate feature experimental_index
only.
impl FallibleStreamingIterator for CodesHandle<CodesIndex>
experimental_index
only.§Errors
The advance()
and next()
methods will return CodesInternal
when internal ecCodes function returns non-zero code.
§type Item = KeyedMessage
type Item = KeyedMessage
§type Error = CodesError
type Error = CodesError
source§fn advance(&mut self) -> Result<(), Self::Error>
fn advance(&mut self) -> Result<(), Self::Error>
source§fn next(&mut self) -> Result<Option<&Self::Item>, Self::Error>
fn next(&mut self) -> Result<Option<&Self::Item>, Self::Error>
source§fn size_hint(&self) -> (usize, Option<usize>)
fn size_hint(&self) -> (usize, Option<usize>)
source§fn all<F>(&mut self, f: F) -> Result<bool, Self::Error>
fn all<F>(&mut self, f: F) -> Result<bool, Self::Error>
source§fn any<F>(&mut self, f: F) -> Result<bool, Self::Error>
fn any<F>(&mut self, f: F) -> Result<bool, Self::Error>
source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
source§fn count(self) -> Result<usize, Self::Error>where
Self: Sized,
fn count(self) -> Result<usize, Self::Error>where
Self: Sized,
source§fn filter<F>(self, f: F) -> Filter<Self, F>
fn filter<F>(self, f: F) -> Filter<Self, F>
source§fn find<F>(&mut self, f: F) -> Result<Option<&Self::Item>, Self::Error>
fn find<F>(&mut self, f: F) -> Result<Option<&Self::Item>, Self::Error>
source§fn for_each<F>(self, f: F) -> Result<(), Self::Error>
fn for_each<F>(self, f: F) -> Result<(), Self::Error>
source§fn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
source§fn map<F, B>(self, f: F) -> Map<Self, F, B>
fn map<F, B>(self, f: F) -> Map<Self, F, B>
source§fn map_ref<F, B>(self, f: F) -> MapRef<Self, F>
fn map_ref<F, B>(self, f: F) -> MapRef<Self, F>
source§fn map_err<F, B>(self, f: F) -> MapErr<Self, F>
fn map_err<F, B>(self, f: F) -> MapErr<Self, F>
source§fn nth(&mut self, n: usize) -> Result<Option<&Self::Item>, Self::Error>
fn nth(&mut self, n: usize) -> Result<Option<&Self::Item>, Self::Error>
nth
element of the iterator.source§fn position<F>(&mut self, f: F) -> Result<Option<usize>, Self::Error>
fn position<F>(&mut self, f: F) -> Result<Option<usize>, Self::Error>
source§fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
n
elements.source§fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
source§impl FallibleStreamingIterator for CodesHandle<GribFile>
impl FallibleStreamingIterator for CodesHandle<GribFile>
§Errors
The advance()
and next()
methods will return CodesInternal
when internal ecCodes function returns non-zero code.
§type Item = KeyedMessage
type Item = KeyedMessage
§type Error = CodesError
type Error = CodesError
source§fn advance(&mut self) -> Result<(), Self::Error>
fn advance(&mut self) -> Result<(), Self::Error>
source§fn next(&mut self) -> Result<Option<&Self::Item>, Self::Error>
fn next(&mut self) -> Result<Option<&Self::Item>, Self::Error>
source§fn size_hint(&self) -> (usize, Option<usize>)
fn size_hint(&self) -> (usize, Option<usize>)
source§fn all<F>(&mut self, f: F) -> Result<bool, Self::Error>
fn all<F>(&mut self, f: F) -> Result<bool, Self::Error>
source§fn any<F>(&mut self, f: F) -> Result<bool, Self::Error>
fn any<F>(&mut self, f: F) -> Result<bool, Self::Error>
source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
source§fn count(self) -> Result<usize, Self::Error>where
Self: Sized,
fn count(self) -> Result<usize, Self::Error>where
Self: Sized,
source§fn filter<F>(self, f: F) -> Filter<Self, F>
fn filter<F>(self, f: F) -> Filter<Self, F>
source§fn find<F>(&mut self, f: F) -> Result<Option<&Self::Item>, Self::Error>
fn find<F>(&mut self, f: F) -> Result<Option<&Self::Item>, Self::Error>
source§fn for_each<F>(self, f: F) -> Result<(), Self::Error>
fn for_each<F>(self, f: F) -> Result<(), Self::Error>
source§fn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
source§fn map<F, B>(self, f: F) -> Map<Self, F, B>
fn map<F, B>(self, f: F) -> Map<Self, F, B>
source§fn map_ref<F, B>(self, f: F) -> MapRef<Self, F>
fn map_ref<F, B>(self, f: F) -> MapRef<Self, F>
source§fn map_err<F, B>(self, f: F) -> MapErr<Self, F>
fn map_err<F, B>(self, f: F) -> MapErr<Self, F>
source§fn nth(&mut self, n: usize) -> Result<Option<&Self::Item>, Self::Error>
fn nth(&mut self, n: usize) -> Result<Option<&Self::Item>, Self::Error>
nth
element of the iterator.source§fn position<F>(&mut self, f: F) -> Result<Option<usize>, Self::Error>
fn position<F>(&mut self, f: F) -> Result<Option<usize>, Self::Error>
source§fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
n
elements.