use std::fs;
use std::path::{Path, PathBuf};
use crate::engine::writer::{AttrSpec, HdfFileWriter};
use crate::error::{Error, Result};
use crate::hl::dataset_builder::DatasetBuilder;
use crate::hl::types::H5Type;
pub struct WritableFile {
writer: HdfFileWriter<fs::File>,
path: PathBuf,
#[allow(dead_code)]
current_group: String,
}
impl WritableFile {
pub fn create<P: AsRef<Path>>(path: P) -> Result<Self> {
let path = path.as_ref().to_path_buf();
let f = fs::File::create(&path)?;
let mut writer = HdfFileWriter::new(f);
writer.begin()?;
writer.create_root_group()?;
Ok(Self {
writer,
path,
current_group: "/".to_string(),
})
}
pub fn create_excl<P: AsRef<Path>>(path: P) -> Result<Self> {
let path = path.as_ref().to_path_buf();
if path.exists() {
return Err(Error::Io(std::io::Error::new(
std::io::ErrorKind::AlreadyExists,
format!("file already exists: {}", path.display()),
)));
}
Self::create(path)
}
pub fn create_group(&mut self, name: &str) -> Result<WritableGroup<'_>> {
self.writer.create_group("/", name)?;
let full_path = format!("/{name}");
Ok(WritableGroup {
writer: &mut self.writer,
path: full_path,
})
}
pub fn new_dataset_builder(&mut self, name: &str) -> DatasetBuilder<'_> {
DatasetBuilder::new(&mut self.writer, "/", name)
}
pub fn add_attr<T: H5Type>(&mut self, name: &str, value: T) -> Result<()> {
let dtype = crate::hl::dataset_builder::dtype_for_type::<T>()?;
let byte_ptr = &value as *const T as *const u8;
let data = unsafe { std::slice::from_raw_parts(byte_ptr, T::type_size()) };
self.writer.add_root_attr(&AttrSpec {
name,
shape: &[],
dtype,
data,
});
Ok(())
}
pub fn link_soft(&mut self, name: &str, target_path: &str) {
self.writer.create_soft_link("/", name, target_path);
}
pub fn link_external(&mut self, name: &str, filename: &str, obj_path: &str) {
self.writer
.create_external_link("/", name, filename, obj_path);
}
pub fn close(mut self) -> Result<crate::hl::file::File> {
self.writer.finalize()?;
crate::hl::file::File::open(&self.path)
}
pub fn flush(&mut self) -> Result<()> {
self.writer.finalize()
}
}
pub struct WritableGroup<'a> {
writer: &'a mut HdfFileWriter<fs::File>,
path: String,
}
impl<'a> WritableGroup<'a> {
pub fn create_group(&mut self, name: &str) -> Result<WritableGroup<'_>> {
self.writer.create_group(&self.path, name)?;
let full_path = format!("{}/{name}", self.path);
Ok(WritableGroup {
writer: self.writer,
path: full_path,
})
}
pub fn new_dataset_builder(&mut self, name: &str) -> DatasetBuilder<'_> {
DatasetBuilder::new(self.writer, &self.path, name)
}
pub fn link_soft(&mut self, name: &str, target_path: &str) {
self.writer.create_soft_link(&self.path, name, target_path);
}
pub fn link_external(&mut self, name: &str, filename: &str, obj_path: &str) {
self.writer
.create_external_link(&self.path, name, filename, obj_path);
}
}