pub mod cf;
pub mod dimension;
pub mod error;
pub mod group;
pub mod types;
pub mod variable;
pub use cf::{CfAttributes, FillValue};
pub use dimension::Dimension;
pub use error::Error;
pub use group::NetCDF4Group;
pub use rustyhdf5::AttrValue;
pub use types::NcType;
pub use variable::Variable;
use std::collections::HashMap;
pub struct NetCDF4File {
hdf5: rustyhdf5::File,
}
impl NetCDF4File {
pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Error> {
let hdf5 = rustyhdf5::File::open(path)?;
Ok(Self { hdf5 })
}
pub fn from_bytes(data: Vec<u8>) -> Result<Self, Error> {
let hdf5 = rustyhdf5::File::from_bytes(data)?;
Ok(Self { hdf5 })
}
pub fn nc_properties(&self) -> Result<Option<String>, Error> {
let attrs = self.hdf5.root().attrs()?;
match attrs.get("_NCProperties") {
Some(AttrValue::String(s)) => Ok(Some(s.clone())),
_ => Ok(None),
}
}
pub fn dimensions(&self) -> Result<Vec<Dimension>, Error> {
dimension::extract_dimensions_from_datasets(&self.hdf5.root(), &self.hdf5)
}
pub fn variables(&self) -> Result<Vec<Variable<'_>>, Error> {
let dims = self.dimensions()?;
variable::build_variables(&self.hdf5.root(), &dims)
}
pub fn variable(&self, name: &str) -> Result<Variable<'_>, Error> {
let dims = self.dimensions()?;
let ds = self
.hdf5
.dataset(name)
.map_err(|_| Error::VariableNotFound(name.to_string()))?;
let shape = ds.shape()?;
let var_dims = variable::match_dimensions_to_variable(&shape, &dims);
Ok(Variable::new(name.to_string(), ds, var_dims))
}
pub fn global_attrs(&self) -> Result<HashMap<String, AttrValue>, Error> {
Ok(self.hdf5.root().attrs()?)
}
pub fn group_names(&self) -> Result<Vec<String>, Error> {
Ok(self.hdf5.root().groups()?)
}
pub fn group(&self, name: &str) -> Result<NetCDF4Group<'_>, Error> {
let hdf5_group = self
.hdf5
.group(name)
.map_err(|_| Error::GroupNotFound(name.to_string()))?;
Ok(NetCDF4Group::new(
name.to_string(),
&self.hdf5,
hdf5_group,
))
}
pub fn hdf5_file(&self) -> &rustyhdf5::File {
&self.hdf5
}
}
impl std::fmt::Debug for NetCDF4File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NetCDF4File")
.field("hdf5", &self.hdf5)
.finish()
}
}