use ndarray::{ArrayViewD, Array, Dimension};
#[allow(unused)]
use ndarray::{Dim, IxDynImpl};
#[allow(unused)]
use num_complex::Complex;
use rustmex_core::convert::{
FromMatlabError,
};
use rustmex_core::{
MatlabClass,
};
#[allow(unused)]
use rustmex_core::mappable::{Mappable, MutMappable};
use rustmex_core::pointers::MxArray;
#[allow(unused)]
use std::ffi::CString;
use rustmex_core::mxArray;
use rustmex_core::numeric::{NumericArray, MatlabNumber};
use crate::char::CharArray;
use crate::numeric::{Numeric, OwnedNumeric};
pub type FromMxError<'a> = FromMatlabError<&'a mxArray>;
pub trait FromMatlab<'a> {
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> where Self: Sized;
}
pub trait ToMatlab {
fn to_matlab(self) -> MxArray;
}
pub trait MatlabScalar: Copy + MatlabNumber {}
macro_rules! impl_mls {
($t:ty) => {impl MatlabScalar for $t {} }
}
impl_mls!(u8);
impl_mls!(i8);
impl_mls!(i16);
impl_mls!(u16);
impl_mls!(u32);
impl_mls!(i32);
impl_mls!(u64);
impl_mls!(i64);
impl_mls!(bool);
impl_mls!(f64);
impl_mls!(f32);
pub trait IntoRust<'a, T> {
fn to_rust(&self) -> Result<T, FromMxError<'a>>;
}
impl<'a, T> IntoRust<'a, T> for &'a mxArray where T: FromMatlab<'a> {
fn to_rust(&self) -> Result<T, FromMxError<'a>> {
T::from_matlab(self)
}
}
impl<'a, T> FromMatlab<'a> for T where
T: MatlabScalar
{
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
let num = Numeric::from_mx_array(mx)?;
let data = num.data();
match data.len() {
1 => Ok(data[0]),
_ => Err(FromMxError::new_badsize(mx))
}
}
}
impl<'a, T> FromMatlab<'a> for ArrayViewD<'a, T> where
Self: From<Numeric<T, &'a mxArray>>,
T: MatlabNumber,
{
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
Ok(Self::from(Numeric::from_mx_array(mx)?))
}
}
impl<'a, T> FromMatlab<'a> for Option<T> where T: FromMatlab<'a> {
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
Ok(if mx.numel() == 0 {
None
} else {
Some(T::from_matlab(mx)?)
})
}
}
impl<'a, T> FromMatlab<'a> for [T; 0] where
T: MatlabNumber
{
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
let num = Numeric::<T, &'a mxArray>::from_mx_array(mx)?;
if num.is_empty() { Ok([]) } else { Err(FromMxError::new_badsize(mx)) }
}
}
impl<'a> FromMatlab<'a> for () {
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
if mx.is_empty() { Ok(()) } else { Err(FromMxError::new_badsize(mx)) }
}
}
impl<'a, T, D> ToMatlab for Array<T, D> where
D: Dimension,
Numeric<T, MxArray>: NumericArray<'a>,
T: MatlabNumber,
Self: 'a,
{
fn to_matlab(self) -> MxArray {
Numeric::from(self).into_inner()
}
}
impl<T> ToMatlab for T where T: MatlabScalar {
fn to_matlab(self) -> MxArray {
Numeric::from(self).into_inner()
}
}
impl<'a> FromMatlab<'a> for CString {
fn from_matlab(mx: &'a mxArray) -> Result<Self, FromMxError<'a>> {
Ok(CharArray::from_mx_array(mx)?.get_cstring())
}
}
impl ToMatlab for () {
fn to_matlab(self) -> MxArray {
OwnedNumeric::from(()).into_inner()
}
}
impl<T: MatlabNumber> ToMatlab for [T; 0] {
fn to_matlab(self) -> MxArray {
OwnedNumeric::<T>::from([]).into_inner()
}
}