use std::ffi::{CString, c_char};
use core::ops::{Deref, DerefMut};
use rustmex_core::{
mxArray,
pointers::{MatlabPtr, MutMatlabPtr, MxArray},
convert::{FromMatlabError},
MatlabClass,
MutMatlabClass,
OwnedMatlabClass,
NewEmpty,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct CharArray<P>(P);
impl<P> Deref for CharArray<P> where P: MatlabPtr {
type Target = mxArray;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<P> DerefMut for CharArray<P> where P: MutMatlabPtr {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
extern "Rust" { fn rustmex_array_to_cstring(mx:*const mxArray) -> *mut c_char; }
impl<P> CharArray<P> where P: MatlabPtr {
pub fn get_cstring(&self) -> CString {
let ptr = unsafe { rustmex_array_to_cstring(self.0.deref()) };
if ptr.is_null() {
panic!("OOM")
}
unsafe { CString::from_raw(ptr) }
}
}
impl<P> MatlabClass<P> for CharArray<P> where P: MatlabPtr {
fn from_mx_array(mx: P) -> Result<Self, FromMatlabError<P>> {
if mx.raw_class_id() != ::rustmex_core::classid::ClassID::Char {
return Err(FromMatlabError::new_badclass(mx));
}
Ok(Self(mx))
}
fn into_inner(self) -> P {
self.0
}
fn inner(&self) -> &P {
&self.0
}
type Owned = CharArray<MxArray>;
fn duplicate(&self) -> Self::Owned {
CharArray(self.0.duplicate())
}
}
impl<P> MutMatlabClass<P> for CharArray<P> where P: MutMatlabPtr {
type AsBorrowed<'a> = CharArray<&'a mxArray> where Self: 'a;
fn as_borrowed<'a>(&'a self) -> Self::AsBorrowed<'a> {
CharArray(self.0.deref())
}
fn inner_mut(&mut self) -> &mut P {
&mut self.0
}
}
impl OwnedMatlabClass for CharArray<MxArray> {
type AsMutable<'a> = CharArray<&'a mut mxArray> where Self: 'a;
fn as_mutable<'a>(&'a mut self) -> Self::AsMutable<'a> {
CharArray(self.0.deref_mut())
}
}
impl NewEmpty for CharArray<MxArray> {
fn new_empty() -> Self {
unimplemented!()
}
}