rust_macios/foundation/
ns_mutable_array.rs

1use std::marker::PhantomData;
2
3use objc::{class, msg_send, runtime::Object, sel, sel_impl};
4
5use crate::{
6    foundation::UInt,
7    object,
8    objective_c_runtime::{
9        id,
10        traits::{FromId, PNSObject},
11    },
12    utils::to_bool,
13};
14
15use super::{ns_array::INSArray, NSArray, NSRange, NSString};
16
17object! {
18    /// A dynamic ordered collection of objects.
19    unsafe pub struct NSMutableArray<T> {
20        _marker: PhantomData<T>,
21    }
22}
23
24/// A mutable, static ordered collection of objects.
25pub trait INSMutableArray<T>: INSArray<T>
26where
27    T: PNSObject,
28{
29    /* Creating and Initializing a Mutable Array
30     */
31
32    /// Creates and returns an NSMutableArray object with enough allocated memory to initially hold a given number of objects.
33    fn tm_array_with_capacity(capacity: usize) -> Self
34    where
35        Self: Sized + FromId,
36    {
37        unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithCapacity: capacity]) }
38    }
39
40    /// Creates and returns a mutable array containing the contents of the file specified by the given path.
41    fn tm_array_with_contents_of_file(path: NSString) -> Self
42    where
43        Self: Sized + FromId,
44    {
45        unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithContentsOfFile: path]) }
46    }
47
48    /// Creates and returns a mutable array containing the contents specified by a given URL.
49    fn tm_array_with_contents_of_url(url: NSString) -> Self
50    where
51        Self: Sized + FromId,
52    {
53        unsafe { Self::from_id(msg_send![Self::m_class(), arrayWithContentsOfURL: url]) }
54    }
55
56    /// Returns an array, initialized with enough memory to initially hold a given number of objects.
57    fn im_init_with_capacity(capacity: UInt) -> Self
58    where
59        Self: Sized + FromId,
60    {
61        unsafe {
62            let cls = Self::m_class();
63            let alloc: id = msg_send![cls, new];
64            let init = msg_send![alloc, initWithCapacity: capacity];
65            Self::from_id(init)
66        }
67    }
68
69    /// Initializes a newly allocated mutable array with the contents of the file specified by a given path
70    fn im_init_with_contents_of_file(&mut self, path: NSString) -> bool {
71        unsafe { to_bool(msg_send![self.m_self(), initWithContentsOfFile: path]) }
72    }
73
74    /* Adding Objects
75     */
76
77    /// Inserts a given object at the end of the array.
78    fn im_add_object(&mut self, object: &T) {
79        unsafe { msg_send![self.m_self(), addObject: object] }
80    }
81
82    /// Adds the objects contained in another given array to the end of the receiving array’s content.
83    fn im_add_objects_from_array(&mut self, other_array: &NSArray<T>) {
84        unsafe { msg_send![self.m_self(), addObjectsFromArray: other_array] }
85    }
86
87    /// Inserts a given object into the array’s contents at a given index.
88    fn im_insert_object_at_index(&mut self, index: UInt, object: &T) {
89        unsafe { msg_send![self.m_self(), insertObject: object atIndex: index] }
90    }
91
92    /* Removing Objects
93     */
94
95    /// Empties the array of all its elements.
96    fn im_remove_all_objects(&mut self) {
97        unsafe { msg_send![self.m_self(), removeAllObjects] }
98    }
99
100    /// Removes the object with the highest-valued index in the array
101    fn im_remove_last_object(&mut self) {
102        unsafe { msg_send![self.m_self(), removeLastObject] }
103    }
104
105    /// Removes all occurrences in the array of a given object.
106    fn im_remove_object(&mut self, object: &T) {
107        unsafe { msg_send![self.m_self(), removeObject: object] }
108    }
109
110    /// Removes all occurrences within a specified range in the array of a given object.
111    fn im_remove_object_in_range(&mut self, object: &T, range: NSRange) {
112        unsafe { msg_send![self.m_self(), removeObject: object inRange: range] }
113    }
114
115    /// Removes the object at index .
116    fn im_remove_object_at_index(&mut self, index: UInt) {
117        unsafe { msg_send![self.m_self(), removeObjectAtIndex: index] }
118    }
119
120    /// Removes all occurrences of a given object in the array.
121    fn im_remove_object_identical_to(&mut self, object: &T) {
122        unsafe { msg_send![self.m_self(), removeObjectIdenticalTo: object] }
123    }
124
125    /// Removes all occurrences of anObject within the specified range in the array.
126    fn im_remove_object_identical_to_in_range(&mut self, object: &T, range: NSRange) {
127        unsafe { msg_send![self.m_self(), removeObjectIdenticalTo: object inRange: range] }
128    }
129
130    /// Removes from the receiving array the objects in another given array.
131    fn im_remove_objects_in_array(&mut self, other_array: &NSArray<T>) {
132        unsafe { msg_send![self.m_self(), removeObjectsInArray: other_array.m_self()] }
133    }
134
135    /// Removes from the array each of the objects within a given range.
136    fn im_remove_objects_in_range(&mut self, range: NSRange) {
137        unsafe { msg_send![self.m_self(), removeObjectsInRange: range] }
138    }
139
140    /* Replacing Objects
141     */
142
143    /// Replaces the object at index with anObject.
144    fn im_replace_object_at_index_with_object(&mut self, index: UInt, object: &T) {
145        unsafe { msg_send![self.m_self(), replaceObjectAtIndex: index withObject: object] }
146    }
147
148    /// Sets the receiving array’s elements to those in another given array.
149    fn im_set_array(&mut self, other_array: &NSArray<T>) {
150        unsafe { msg_send![self.m_self(), setArray: other_array.m_self()] }
151    }
152}
153
154impl<T> INSArray<T> for NSMutableArray<T> where T: PNSObject + FromId {}
155
156impl<T> INSMutableArray<T> for NSMutableArray<T> where T: PNSObject + FromId {}
157
158impl<T> From<id> for NSMutableArray<T> {
159    #[allow(clippy::not_unsafe_ptr_arg_deref)]
160    fn from(obj: id) -> Self {
161        unsafe { Self::from_id(obj) }
162    }
163}
164
165impl<T> From<&[T]> for NSMutableArray<T>
166where
167    T: PNSObject,
168{
169    fn from(array: &[T]) -> Self {
170        unsafe {
171            let cls: *mut Object = msg_send![class!(NSArray),
172                arrayWithObjects:array.as_ptr()
173                count:array.len()
174            ];
175            NSMutableArray::from(cls)
176        }
177    }
178}
179
180impl<T> From<UInt> for NSMutableArray<T>
181where
182    T: PNSObject,
183{
184    fn from(capacity: UInt) -> Self {
185        unsafe {
186            let cls: *mut Object = msg_send![class!(NSArray), arrayWithCapacity: capacity];
187            NSMutableArray::from(cls)
188        }
189    }
190}