use std::{ffi::CString, ops::Deref, str::FromStr}; use rustmex::{ char::CharArray, numeric::{Numeric, NumericArray}, MatlabClass, MxArray, }; use crate::error::{Error, MapMexError, SResult}; /// Trait to convert a Matlab type into a Rust type pub trait IntoRustType<T> { fn into_rust(self) -> SResult<T>; } impl IntoRustType<CString> for MxArray { fn into_rust(self) -> SResult<CString> { Ok(CharArray::from_mx_array(self) .mexerr(Error::InvalidMatlabType("use a string instead".into()))? .get_cstring()) } } impl IntoRustType<String> for MxArray { fn into_rust(self) -> SResult<String> { let c: CString = self.into_rust()?; Ok(c.into_string()?) } } impl IntoRustType<f64> for MxArray { fn into_rust(self) -> SResult<f64> { let out = Numeric::<f64, _>::from_mx_array(self) .mexerr(Error::InvalidMatlabType( "use a numerical type instead".into(), ))? .data() .first() .mexerr(Error::Parse)? .to_owned(); Ok(out) } } impl IntoRustType<f32> for MxArray { fn into_rust(self) -> SResult<f32> { let out = Numeric::<f32, _>::from_mx_array(self) .mexerr(Error::InvalidMatlabType("cast to a single instead".into()))? .data() .first() .mexerr(Error::Parse)? .to_owned(); Ok(out) } } impl IntoRustType<Vec<f64>> for MxArray { fn into_rust(self) -> SResult<Vec<f64>> { let out = Numeric::<f64, _>::from_mx_array(self) .mexerr(Error::InvalidMatlabType( "use a numerical type instead".into(), ))? .data() .to_owned(); Ok(out) } } /// Trait to convert a Rust type into a Matlab type pub trait IntoMatlabType { fn into_matlab(self) -> SResult<MxArray>; } impl IntoMatlabType for Vec<f64> { fn into_matlab(self) -> SResult<MxArray> { let len = self.len(); Ok(Numeric::<f64, _>::new(self.into_boxed_slice(), &[len]) .unwrap() .deref() .to_owned()) } } impl IntoMatlabType for Vec<f32> { fn into_matlab(self) -> SResult<MxArray> { let len = self.len(); Ok(Numeric::<f32, _>::new(self.into_boxed_slice(), &[len]) .unwrap() .deref() .to_owned()) } } /// Functions available to the user #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Mode { Open, Close, Read, Write, } impl FromStr for Mode { type Err = crate::Error; fn from_str(s: &str) -> Result<Self, Self::Err> { match s { "Open" => Ok(Mode::Open), "Close" => Ok(Mode::Close), "Read" => Ok(Mode::Read), "Write" => Ok(Mode::Write), _ => Err(Error::InvalidMode), } } }