use super::errors::{Error, Result};
use super::fitsfile::FitsFile;
use super::headers::{ReadsKey, WritesKey};
#[derive(Debug, Clone)]
pub struct FitsHdu {
pub(crate) hdu_index: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HduInfo {
ImageInfo {
shape: Vec<usize>,
image_type: super::images::ImageType,
},
TableInfo {
column_count: usize,
row_count: usize,
},
AnyInfo,
}
impl FitsHdu {
pub fn read_key<T: ReadsKey>(&self, file: &FitsFile, name: &str) -> Result<T> {
T::read_key(file, self, name)
}
pub fn write_key<T: WritesKey>(
&self,
file: &mut FitsFile,
name: &str,
value: &T,
) -> Result<()> {
T::write_key(file, self, name, value)
}
pub fn info(&self, file: &FitsFile) -> Result<HduInfo> {
let fits_data = crate::hdu::parse_fits(file.data())?;
let hdu = fits_data.get(self.hdu_index).ok_or(Error::Message(format!(
"HDU index {} out of range",
self.hdu_index
)))?;
match &hdu.info {
crate::hdu::HduInfo::Primary { bitpix, naxes } => {
let image_type = super::images::ImageType::from_bitpix(*bitpix)?;
Ok(HduInfo::ImageInfo {
shape: naxes.clone(),
image_type,
})
}
crate::hdu::HduInfo::Image { bitpix, naxes } => {
let image_type = super::images::ImageType::from_bitpix(*bitpix)?;
Ok(HduInfo::ImageInfo {
shape: naxes.clone(),
image_type,
})
}
crate::hdu::HduInfo::AsciiTable {
naxis2, tfields, ..
} => Ok(HduInfo::TableInfo {
column_count: *tfields,
row_count: *naxis2,
}),
crate::hdu::HduInfo::BinaryTable {
naxis2, tfields, ..
} => Ok(HduInfo::TableInfo {
column_count: *tfields,
row_count: *naxis2,
}),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::compat::fitsfile::FitsFile;
#[test]
fn hdu_info_primary_empty() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("test.fits");
let f = FitsFile::create(&path).open().unwrap();
let hdu = f.primary_hdu().unwrap();
let info = hdu.info(&f).unwrap();
match info {
HduInfo::ImageInfo { shape, .. } => {
assert!(shape.is_empty());
}
_ => panic!("Expected ImageInfo"),
}
}
#[test]
fn hdu_read_write_key() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("test.fits");
let mut f = FitsFile::create(&path).open().unwrap();
let hdu = f.primary_hdu().unwrap();
hdu.write_key(&mut f, "TESTVAL", &42i64).unwrap();
let val: i64 = hdu.read_key(&f, "TESTVAL").unwrap();
assert_eq!(val, 42);
}
}