1use std::ops::{Deref, DerefMut, Drop};
6use std::clone::Clone;
7use std::borrow::{ToOwned, Borrow};
8use std::convert::AsRef;
9use std::ptr::NonNull;
10
11use crate::{mxArray, MatlabClass};
12
13use crate::shim::{
14 rustmex_duplicate_array,
15 rustmex_destroy_array,
16};
17
18pub trait MatlabPtr: Deref<Target = mxArray> {
25
26 fn is_a<W>(self) -> Result<W, crate::convert::FromMatlabError<Self>> where
35 W: MatlabClass<Self>,
36 Self: Sized,
37 {
38 W::from_mx_array(self)
39 }
40}
41
42impl<'a> MatlabPtr for &'a mut mxArray { }
43impl<'a> MatlabPtr for &'a mxArray { }
44impl MatlabPtr for MxArray {}
45
46pub trait MutMatlabPtr: DerefMut<Target = mxArray> + MatlabPtr {}
47impl<T> MutMatlabPtr for T where T: DerefMut<Target = mxArray> + MatlabPtr {}
48
49#[repr(transparent)]
61#[derive(Debug)]
62pub struct MxArray(NonNull<mxArray>);
63
64impl Drop for MxArray {
65 fn drop(&mut self) {
66 unsafe { rustmex_destroy_array(self.0.as_mut()) };
67 }
68}
69
70impl Deref for MxArray {
71 type Target = mxArray;
72
73 fn deref(&self) -> &Self::Target {
74 unsafe { self.0.as_ref() }
75 }
76}
77
78impl DerefMut for MxArray {
79 fn deref_mut(&mut self) -> &mut Self::Target {
80 unsafe { self.0.as_mut() }
81 }
82}
83
84impl mxArray {
85 pub fn duplicate(&self) -> MxArray {
91 let ptr = unsafe { rustmex_duplicate_array(self) };
92 if ptr.is_null() {
93 panic!("OOM");
94 }
95 unsafe { MxArray::assume_responsibility(&mut *ptr ) }
96 }
97}
98
99impl Clone for MxArray {
100 fn clone(&self) -> Self {
101 self.duplicate()
102 }
103}
104
105impl Borrow<mxArray> for MxArray {
106 fn borrow(&self) -> &mxArray {
107 self.deref()
108 }
109}
110
111impl ToOwned for mxArray {
112 type Owned = MxArray;
113
114 fn to_owned(&self) -> Self::Owned {
115 self.duplicate()
116 }
117}
118
119impl AsRef<mxArray> for mxArray {
120 fn as_ref(&self) -> &mxArray {
121 self
122 }
123}
124
125impl AsRef<mxArray> for MxArray {
126 fn as_ref(&self) -> &mxArray {
127 self.deref()
128 }
129
130}
131
132impl MxArray {
133 pub unsafe fn assume_responsibility(mx: &'static mut mxArray) -> Self {
142 Self(NonNull::new_unchecked(mx as *mut mxArray))
143 }
144
145 pub unsafe fn assume_responsibility_ptr(mx: *mut mxArray) -> Self {
147 Self(NonNull::new(mx).expect("Non-null pointer"))
148 }
149
150 pub unsafe fn transfer_responsibility(o: Self) -> &'static mut mxArray {
155 &mut *Self::transfer_responsibility_ptr(o)
156 }
157
158 pub unsafe fn transfer_responsibility_ptr(o: Self) -> *mut mxArray {
160 let ptr = o.0.as_ptr();
161 std::mem::forget(o);
162 ptr
163 }
164}