1use crate::{MatioError, Result};
2use std::{fs, io, marker::PhantomData, ops::Deref, path::Path, ptr};
3
4pub struct MatFile<'a> {
6 pub(crate) mat_t: *mut ffi::mat_t,
7 marker: PhantomData<&'a ffi::mat_t>,
8}
9pub struct MatFileRead<'a>(MatFile<'a>);
11impl<'a> Deref for MatFileRead<'a> {
12 type Target = MatFile<'a>;
13 fn deref(&self) -> &Self::Target {
14 &self.0
15 }
16}
17impl<'a> MatFileRead<'a> {
18 pub fn info(&self) {
20 let matvar_t = unsafe { ffi::Mat_VarReadNextInfo(self.mat_t) };
21 if !matvar_t.is_null() {
22 let name = unsafe { std::ffi::CStr::from_ptr((*matvar_t).name) };
23 let rank = unsafe { (*matvar_t).rank } as usize;
24 let mut dims: Vec<u64> = Vec::with_capacity(rank);
25 unsafe {
26 ptr::copy((*matvar_t).dims as *mut _, dims.as_mut_ptr(), rank);
27 dims.set_len(rank);
28 }
29 println!(
30 "Matlab var.: {:?} with dims: {:?}",
31 name.to_str().unwrap(),
32 dims
33 );
34 self.info();
35 }
36 }
37}
38pub struct MatFileWrite<'a>(MatFile<'a>);
40impl<'a> Deref for MatFileWrite<'a> {
41 type Target = MatFile<'a>;
42 fn deref(&self) -> &Self::Target {
43 &self.0
44 }
45}
46impl<'a> MatFile<'a> {
47 pub(crate) fn from_ptr(mat_t: *mut ffi::mat_t) -> MatFile<'a> {
48 MatFile {
49 mat_t,
50 marker: PhantomData,
51 }
52 }
53 pub fn load<P: AsRef<Path>>(path: P) -> Result<MatFileRead<'a>> {
63 let attrs = fs::metadata(&path)?;
64 if attrs.is_file() {
65 let mat_name = std::ffi::CString::new(path.as_ref().to_str().unwrap())?;
66 let mat_t =
67 unsafe { ffi::Mat_Open(mat_name.as_ptr(), ffi::mat_acc_MAT_ACC_RDONLY as i32) };
68 if mat_t.is_null() {
69 Err(MatioError::MatOpen(
70 path.as_ref().to_str().unwrap().to_string(),
71 ))
72 } else {
73 Ok(MatFileRead(MatFile::from_ptr(mat_t)))
74 }
75 } else {
76 Err(MatioError::NoFile(io::Error::new(
77 io::ErrorKind::NotFound,
78 format!("mat file {:?} not found", path.as_ref()),
79 )))
80 }
81 }
82 pub fn save<P: AsRef<Path>>(path: P) -> Result<MatFileWrite<'a>> {
92 let mat_name = std::ffi::CString::new(path.as_ref().to_str().unwrap())?;
93 let mat_t =
94 unsafe { ffi::Mat_CreateVer(mat_name.as_ptr(), ptr::null(), ffi::mat_ft_MAT_FT_MAT5) };
95 if mat_t.is_null() {
96 Err(MatioError::MatOpen(
97 path.as_ref().to_str().unwrap().to_string(),
98 ))
99 } else {
100 Ok(MatFileWrite(MatFile::from_ptr(mat_t)))
101 }
102 }
103}
104
105impl<'a> Drop for MatFile<'a> {
106 fn drop(&mut self) {
107 if unsafe { ffi::Mat_Close(self.mat_t) } != 0 {
108 panic!("failed to close matfile")
109 }
110 }
111}