use std::marker::PhantomData;
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
use crate::{
foundation::UInt,
object,
objective_c_runtime::{
id,
traits::{FromId, PNSObject},
},
utils::to_bool,
};
use super::{ns_array::INSArray, NSArray, NSRange, NSString};
object! {
unsafe pub struct NSMutableArray<T> {
_marker: PhantomData<T>,
}
}
pub trait INSMutableArray<T>: INSArray<T>
where
T: PNSObject,
{
fn tm_array_with_capacity(capacity: usize) -> Self
where
Self: Sized + FromId,
{
unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithCapacity: capacity]) }
}
fn tm_array_with_contents_of_file(path: NSString) -> Self
where
Self: Sized + FromId,
{
unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithContentsOfFile: path]) }
}
fn tm_array_with_contents_of_url(url: NSString) -> Self
where
Self: Sized + FromId,
{
unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithContentsOfURL: url]) }
}
fn im_init_with_capacity(capacity: UInt) -> Self
where
Self: Sized + FromId,
{
unsafe {
let cls = Self::m_class();
let alloc: id = msg_send![cls, new];
let init = msg_send![alloc, initWithCapacity: capacity];
Self::from_id(init)
}
}
fn im_init_with_contents_of_file(&mut self, path: NSString) -> bool {
unsafe { to_bool(msg_send![self.m_self(), initWithContentsOfFile: path]) }
}
fn im_add_object(&mut self, object: &T) {
unsafe { msg_send![self.m_self(), addObject: object] }
}
fn im_add_objects_from_array(&mut self, other_array: &NSArray<T>) {
unsafe { msg_send![self.m_self(), addObjectsFromArray: other_array] }
}
fn im_insert_object_at_index(&mut self, index: UInt, object: &T) {
unsafe { msg_send![self.m_self(), insertObject: object atIndex: index] }
}
fn im_remove_all_objects(&mut self) {
unsafe { msg_send![self.m_self(), removeAllObjects] }
}
fn im_remove_last_object(&mut self) {
unsafe { msg_send![self.m_self(), removeLastObject] }
}
fn im_remove_object(&mut self, object: &T) {
unsafe { msg_send![self.m_self(), removeObject: object] }
}
fn im_remove_object_in_range(&mut self, object: &T, range: NSRange) {
unsafe { msg_send![self.m_self(), removeObject: object inRange: range] }
}
fn im_remove_object_at_index(&mut self, index: UInt) {
unsafe { msg_send![self.m_self(), removeObjectAtIndex: index] }
}
fn im_remove_object_identical_to(&mut self, object: &T) {
unsafe { msg_send![self.m_self(), removeObjectIdenticalTo: object] }
}
fn im_remove_object_identical_to_in_range(&mut self, object: &T, range: NSRange) {
unsafe { msg_send![self.m_self(), removeObjectIdenticalTo: object inRange: range] }
}
fn im_remove_objects_in_array(&mut self, other_array: &NSArray<T>) {
unsafe { msg_send![self.m_self(), removeObjectsInArray: other_array.m_self()] }
}
fn im_remove_objects_in_range(&mut self, range: NSRange) {
unsafe { msg_send![self.m_self(), removeObjectsInRange: range] }
}
fn im_replace_object_at_index_with_object(&mut self, index: UInt, object: &T) {
unsafe { msg_send![self.m_self(), replaceObjectAtIndex: index withObject: object] }
}
fn im_set_array(&mut self, other_array: &NSArray<T>) {
unsafe { msg_send![self.m_self(), setArray: other_array.m_self()] }
}
}
impl<T> INSArray<T> for NSMutableArray<T> where T: PNSObject + FromId {}
impl<T> INSMutableArray<T> for NSMutableArray<T> where T: PNSObject + FromId {}
impl<T> From<id> for NSMutableArray<T> {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
fn from(obj: id) -> Self {
unsafe { Self::from_id(obj) }
}
}
impl<T> From<&[T]> for NSMutableArray<T>
where
T: PNSObject,
{
fn from(array: &[T]) -> Self {
unsafe {
let cls: *mut Object = msg_send![class!(NSArray),
arrayWithObjects:array.as_ptr()
count:array.len()
];
NSMutableArray::from(cls)
}
}
}
impl<T> From<UInt> for NSMutableArray<T>
where
T: PNSObject,
{
fn from(capacity: UInt) -> Self {
unsafe {
let cls: *mut Object = msg_send![class!(NSArray), arrayWithCapacity: capacity];
NSMutableArray::from(cls)
}
}
}