1pub mod cf;
27pub mod dimension;
28pub mod error;
29pub mod group;
30pub mod types;
31pub mod variable;
32
33pub use cf::{CfAttributes, FillValue};
34pub use dimension::Dimension;
35pub use error::Error;
36pub use group::NetCDF4Group;
37pub use rustyhdf5::AttrValue;
38pub use types::NcType;
39pub use variable::Variable;
40
41use std::collections::HashMap;
42
43pub struct NetCDF4File {
48 hdf5: rustyhdf5::File,
49}
50
51impl NetCDF4File {
52 pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Error> {
54 let hdf5 = rustyhdf5::File::open(path)?;
55 Ok(Self { hdf5 })
56 }
57
58 pub fn from_bytes(data: Vec<u8>) -> Result<Self, Error> {
60 let hdf5 = rustyhdf5::File::from_bytes(data)?;
61 Ok(Self { hdf5 })
62 }
63
64 pub fn nc_properties(&self) -> Result<Option<String>, Error> {
69 let attrs = self.hdf5.root().attrs()?;
70 match attrs.get("_NCProperties") {
71 Some(AttrValue::String(s)) => Ok(Some(s.clone())),
72 _ => Ok(None),
73 }
74 }
75
76 pub fn dimensions(&self) -> Result<Vec<Dimension>, Error> {
78 dimension::extract_dimensions_from_datasets(&self.hdf5.root(), &self.hdf5)
79 }
80
81 pub fn variables(&self) -> Result<Vec<Variable<'_>>, Error> {
83 let dims = self.dimensions()?;
84 variable::build_variables(&self.hdf5.root(), &dims)
85 }
86
87 pub fn variable(&self, name: &str) -> Result<Variable<'_>, Error> {
89 let dims = self.dimensions()?;
90 let ds = self
91 .hdf5
92 .dataset(name)
93 .map_err(|_| Error::VariableNotFound(name.to_string()))?;
94 let shape = ds.shape()?;
95 let var_dims = variable::match_dimensions_to_variable(&shape, &dims);
96 Ok(Variable::new(name.to_string(), ds, var_dims))
97 }
98
99 pub fn global_attrs(&self) -> Result<HashMap<String, AttrValue>, Error> {
101 Ok(self.hdf5.root().attrs()?)
102 }
103
104 pub fn group_names(&self) -> Result<Vec<String>, Error> {
106 Ok(self.hdf5.root().groups()?)
107 }
108
109 pub fn group(&self, name: &str) -> Result<NetCDF4Group<'_>, Error> {
111 let hdf5_group = self
112 .hdf5
113 .group(name)
114 .map_err(|_| Error::GroupNotFound(name.to_string()))?;
115 Ok(NetCDF4Group::new(
116 name.to_string(),
117 &self.hdf5,
118 hdf5_group,
119 ))
120 }
121
122 pub fn hdf5_file(&self) -> &rustyhdf5::File {
124 &self.hdf5
125 }
126}
127
128impl std::fmt::Debug for NetCDF4File {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 f.debug_struct("NetCDF4File")
131 .field("hdf5", &self.hdf5)
132 .finish()
133 }
134}