1use std::ffi::c_void;
27use std::marker::PhantomData;
28use std::ptr::NonNull;
29
30use mtl_sys::{class, msg_send_0, msg_send_1, msg_send_2, sel};
31
32use crate::enumerator::Enumerator;
33use crate::object::{Copying, Object, Referencing};
34use crate::types::UInteger;
35
36#[repr(transparent)]
40pub struct Array<T = Object> {
41 inner: NonNull<c_void>,
42 _marker: PhantomData<T>,
43}
44
45impl<T> Clone for Array<T> {
46 fn clone(&self) -> Self {
47 Self {
48 inner: self.inner,
49 _marker: PhantomData,
50 }
51 }
52}
53
54impl<T> Array<T> {
55 #[inline]
59 pub fn array() -> Option<Self> {
60 unsafe {
61 let ptr: *mut c_void = msg_send_0(class!(NSArray).as_ptr(), sel!(array));
62 Self::from_ptr(ptr)
63 }
64 }
65
66 #[inline]
70 pub fn array_with_object(object: *const T) -> Option<Self> {
71 unsafe {
72 let ptr: *mut c_void =
73 msg_send_1(class!(NSArray).as_ptr(), sel!(arrayWithObject:), object);
74 Self::from_ptr(ptr)
75 }
76 }
77
78 #[inline]
82 pub fn array_with_objects(objects: *const *const T, count: UInteger) -> Option<Self> {
83 unsafe {
84 let ptr: *mut c_void = msg_send_2(
85 class!(NSArray).as_ptr(),
86 sel!(arrayWithObjects:count:),
87 objects,
88 count,
89 );
90 Self::from_ptr(ptr)
91 }
92 }
93
94 #[inline]
98 pub fn alloc() -> Option<Self> {
99 unsafe {
100 let ptr: *mut c_void = msg_send_0(class!(NSArray).as_ptr(), sel!(alloc));
101 Self::from_ptr(ptr)
102 }
103 }
104
105 #[inline]
109 pub fn init(&self) -> Option<Self> {
110 unsafe {
111 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
112 Self::from_ptr(ptr)
113 }
114 }
115
116 #[inline]
120 pub fn init_with_objects(&self, objects: *const *const T, count: UInteger) -> Option<Self> {
121 unsafe {
122 let ptr: *mut c_void =
123 msg_send_2(self.as_ptr(), sel!(initWithObjects:count:), objects, count);
124 Self::from_ptr(ptr)
125 }
126 }
127
128 #[inline]
132 pub fn init_with_coder(&self, coder: *const c_void) -> Option<Self> {
133 unsafe {
134 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithCoder:), coder);
135 Self::from_ptr(ptr)
136 }
137 }
138
139 #[inline]
143 pub fn object(&self, index: UInteger) -> *mut T {
144 unsafe { msg_send_1(self.as_ptr(), sel!(objectAtIndex:), index) }
145 }
146
147 #[inline]
151 pub fn count(&self) -> UInteger {
152 unsafe { msg_send_0(self.as_ptr(), sel!(count)) }
153 }
154
155 #[inline]
159 pub fn object_enumerator(&self) -> Option<Enumerator<T>> {
160 unsafe {
161 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(objectEnumerator));
162 Enumerator::from_ptr(ptr)
163 }
164 }
165
166 #[inline]
172 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
173 NonNull::new(ptr).map(|inner| Self {
174 inner,
175 _marker: PhantomData,
176 })
177 }
178}
179
180impl<T> Referencing for Array<T> {
181 #[inline]
182 fn as_ptr(&self) -> *const c_void {
183 self.inner.as_ptr()
184 }
185}
186
187impl<T> Copying for Array<T> {
188 #[inline]
189 fn copy(&self) -> Option<Self> {
190 unsafe {
191 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
192 Self::from_ptr(ptr)
193 }
194 }
195}
196
197unsafe impl<T: Send> Send for Array<T> {}
199unsafe impl<T: Sync> Sync for Array<T> {}
200
201impl<T> std::fmt::Debug for Array<T> {
202 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
203 f.debug_struct("Array")
204 .field("ptr", &self.inner)
205 .field("count", &self.count())
206 .finish()
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn test_array_size() {
216 assert_eq!(
218 std::mem::size_of::<Array<Object>>(),
219 std::mem::size_of::<*mut c_void>()
220 );
221 }
222}