Skip to content

Commit

Permalink
feat: add FitsFile::file_path method to access FitsFile file path (
Browse files Browse the repository at this point in the history
…#367)

Include a method to access the file path of the `FitsFile`.

During my investigation I found that there was no reason to make it
optional. Given this, I have made the field/function return non-optional
as well.

Also: it is stored as a `PathBuf` internally, and inherently refers to a
path on disk, so let's return a `Path` in that case.

Closes #366
  • Loading branch information
simonrw authored Oct 31, 2024
1 parent 01ed20c commit b3c5069
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 15 deletions.
64 changes: 55 additions & 9 deletions fitsio/src/fitsfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::errors::{check_status, Error, Result};
use crate::hdu::{DescribesHdu, FitsHdu, FitsHduIterator, HduInfo};
use crate::images::{ImageDescription, ImageType};
use crate::longnam::*;
use crate::stringutils::{self, status_to_string};
use crate::stringutils::{self, buf_to_string, status_to_string};
use crate::tables::{ColumnDataDescription, ConcreteColumnDescription};
use std::ffi;
use std::io::{self, Write};
Expand All @@ -21,7 +21,7 @@ use std::ptr;

/// Main entry point to the FITS file format
pub struct FitsFile {
filename: Option<PathBuf>,
file_path: PathBuf,
open_mode: FileOpenMode,
pub(crate) fptr: ptr::NonNull<fitsfile>,
}
Expand Down Expand Up @@ -64,7 +64,7 @@ impl FitsFile {
Some(p) => FitsFile {
fptr: p,
open_mode: FileOpenMode::READONLY,
filename: Some(file_path.to_path_buf()),
file_path: file_path.to_path_buf(),
},
None => unimplemented!(),
})
Expand Down Expand Up @@ -106,7 +106,7 @@ impl FitsFile {
Some(p) => FitsFile {
fptr: p,
open_mode: FileOpenMode::READWRITE,
filename: Some(file_path.to_path_buf()),
file_path: file_path.to_path_buf(),
},
None => unimplemented!(),
})
Expand Down Expand Up @@ -255,6 +255,11 @@ impl FitsFile {
self.hdu(0)
}

/// Return the file path of the file
pub fn file_path(&self) -> &Path {
&self.file_path
}

/// Return the number of HDU objects in the file
fn num_hdus(&mut self) -> Result<usize> {
let mut status = 0;
Expand Down Expand Up @@ -650,9 +655,7 @@ impl FitsFile {
where
W: Write,
{
if let Some(ref filename) = self.filename {
writeln!(w, "\n file: {:?}", filename)?;
}
writeln!(w, "\n file: {}", self.file_path.display())?;
match self.open_mode {
FileOpenMode::READONLY => writeln!(w, " mode: READONLY")?,
FileOpenMode::READWRITE => writeln!(w, " mode: READWRITE")?,
Expand Down Expand Up @@ -783,8 +786,13 @@ impl FitsFile {
/// # }
/// ```
pub unsafe fn from_raw(fptr: *mut fitsfile, mode: FileOpenMode) -> Result<FitsFile> {
let mut buf = vec![0; 1025];
let mut status = 0;
unsafe { fits_file_name(fptr, buf.as_mut_ptr(), &mut status) };
let s = buf_to_string(&buf)?;

Ok(Self {
filename: None,
file_path: PathBuf::from(s),
open_mode: mode,
fptr: ptr::NonNull::new(fptr).ok_or(Error::NullPointer)?,
})
Expand Down Expand Up @@ -905,7 +913,7 @@ where
Some(p) => FitsFile {
fptr: p,
open_mode: FileOpenMode::READWRITE,
filename: Some(file_path.to_path_buf()),
file_path: file_path.to_path_buf(),
},
None => unimplemented!(),
};
Expand Down Expand Up @@ -1051,14 +1059,18 @@ casesensitivity_into_impl!(i64);

#[cfg(test)]
mod test {
use libc::c_int;

use crate::errors::Error;
use crate::fitsfile::FitsFile;
use crate::fitsfile::{FileOpenMode, ImageDescription};
use crate::hdu::{FitsHdu, HduInfo};
use crate::images::ImageType;
use crate::tables::{ColumnDataType, ColumnDescription};
use crate::testhelpers::{duplicate_test_file, with_temp_file};
use std::ffi::CString;
use std::path::Path;
use std::ptr;

#[test]
fn test_opening_an_existing_file() {
Expand Down Expand Up @@ -1610,4 +1622,38 @@ mod test {
}
});
}

#[test]
fn test_get_filename() {
use crate::longnam::fits_open_file;
use fitsio_sys::fitsfile;

duplicate_test_file(|src_filename| {
let f = FitsFile::open(src_filename).unwrap();

// open file manually
let mut fptr: *mut fitsfile = ptr::null_mut();
let mut status = 0;
let c_filename = CString::new(src_filename).unwrap();
unsafe {
fits_open_file(
&mut fptr as *mut *mut fitsfile,
c_filename.as_ptr(),
FileOpenMode::READONLY as c_int,
&mut status,
)
};

if status != 0 {
panic!("error opening file manually");
}

assert!(!fptr.is_null());

let f2 = unsafe { FitsFile::from_raw(fptr, FileOpenMode::READONLY).unwrap() };

assert_eq!(f.file_path(), Path::new(src_filename));
assert_eq!(f2.file_path(), Path::new(src_filename));
});
}
}
20 changes: 14 additions & 6 deletions fitsio/src/longnam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
#![allow(unused_imports, dead_code)]

pub(crate) use crate::sys::{
ffclos, ffcopy, ffcrim, ffcrtb, ffdcol, ffdhdu, ffflmd, ffgbcl, ffgcdw, ffgcno, ffgcvb, ffgcvd,
ffgcve, ffgcvi, ffgcvj, ffgcvjj, ffgcvk, ffgcvl, ffgcvs, ffgcvsb, ffgcvui, ffgcvuj, ffgcvujj,
ffgcvuk, ffgcx, ffghdn, ffghdt, ffgidm, ffgiet, ffgisz, ffgkyd, ffgkye, ffgkyj, ffgkyjj,
ffgkyl, ffgkys, ffgncl, ffgnrw, ffgpv, ffgsv, fficol, ffinit, ffmahd, ffmnhd, ffopen, ffpcl,
ffpcls, ffpclx, ffphps, ffpky, ffpkyd, ffpkye, ffpkys, ffppr, ffpss, ffrsim, ffthdu, fitsfile,
LONGLONG,
ffclos, ffcopy, ffcrim, ffcrtb, ffdcol, ffdhdu, ffflmd, ffflnm, ffgbcl, ffgcdw, ffgcno, ffgcvb,
ffgcvd, ffgcve, ffgcvi, ffgcvj, ffgcvjj, ffgcvk, ffgcvl, ffgcvs, ffgcvsb, ffgcvui, ffgcvuj,
ffgcvujj, ffgcvuk, ffgcx, ffghdn, ffghdt, ffgidm, ffgiet, ffgisz, ffgkyd, ffgkye, ffgkyj,
ffgkyjj, ffgkyl, ffgkys, ffgncl, ffgnrw, ffgpv, ffgsv, fficol, ffinit, ffmahd, ffmnhd, ffopen,
ffpcl, ffpcls, ffpclx, ffphps, ffpky, ffpkyd, ffpkye, ffpkys, ffppr, ffpss, ffrsim, ffthdu,
fitsfile, LONGLONG,
};
pub use libc::{
c_char, c_double, c_float, c_int, c_long, c_schar, c_short, c_uchar, c_uint, c_ulong,
Expand Down Expand Up @@ -650,3 +650,11 @@ pub(crate) unsafe fn fits_write_key(
) -> c_int {
ffpky(fptr, datatype, keyname, value, comm, status)
}

pub(crate) unsafe fn fits_file_name(
fptr: *mut fitsfile,
filename: *mut c_char,
status: *mut c_int,
) -> c_int {
ffflnm(fptr, filename, status)
}

0 comments on commit b3c5069

Please sign in to comment.