rust_macios/foundation/
ns_mutable_string.rs1use objc::{msg_send, sel, sel_impl};
2
3use crate::{
4 foundation::INSString,
5 object,
6 objective_c_runtime::{
7 id,
8 macros::interface_impl,
9 traits::{FromId, PNSObject},
10 },
11};
12
13use super::{
14 NSComparisonResult, NSRange, NSString, NSStringCompareOptions, NSStringTransform, UInt,
15};
16
17object! {
18 unsafe pub struct NSMutableString;
20}
21
22#[interface_impl(NSString)]
23impl NSMutableString {
24 #[method]
38 pub fn string_with_capacity(capacity: UInt) -> NSMutableString {
39 unsafe {
40 NSMutableString::from_id(msg_send![Self::m_class(), stringWithCapacity: capacity])
41 }
42 }
43
44 #[method]
51 pub fn init_with_capacity(mut self, capacity: UInt) -> NSMutableString
52 where
53 Self: Sized,
54 {
55 unsafe { msg_send![self.m_self(), initWithCapacity: capacity] }
56 }
57
58 #[method]
67 pub fn append_string<S>(&mut self, string: S)
68 where
69 S: INSString,
70 {
71 unsafe { msg_send![self.m_self(), appendString: string] }
72 }
73
74 #[method]
87 pub fn apply_transform_reverse_range_updated_range(
88 &mut self,
89 transform: NSStringTransform,
90 reverse: bool,
91 range: NSRange,
92 out_range: NSRange,
93 ) -> bool {
94 unsafe {
95 msg_send![
96 self.m_self(),
97 applyTransform: transform
98 reverse: reverse
99 range: range
100 updatedRange: out_range
101 ]
102 }
103 }
104
105 #[method]
111 pub fn delete_characters_in_range(&mut self, range: NSRange) {
112 unsafe { msg_send![self.m_self(), deleteCharactersInRange: range] }
113 }
114
115 #[method]
123 pub fn insert_string_at_index<S>(&mut self, string: S, loc: UInt)
124 where
125 S: INSString,
126 {
127 unsafe { msg_send![self.m_self(), insertString: string atIndex: loc] }
128 }
129
130 #[method]
137 pub fn replace_characters_in_range_with_string<S>(&mut self, range: NSRange, string: S)
138 where
139 S: INSString,
140 {
141 unsafe {
142 msg_send![
143 self.m_self(),
144 replaceCharactersInRange: range
145 withString: string
146 ]
147 }
148 }
149
150 #[method]
153 pub fn replace_occurrences_of_string_with_string_options_range<S>(
154 &mut self,
155 target: NSString,
156 replacement: S,
157 options: NSStringCompareOptions,
158 search_range: NSRange,
159 ) -> UInt
160 where
161 S: INSString,
162 {
163 unsafe {
164 msg_send![
165 self.m_self(),
166 replaceOccurrencesOfString: target
167 withString: replacement
168 options: options
169 range: search_range
170 ]
171 }
172 }
173
174 #[method]
180 pub fn set_string<S>(&mut self, string: S)
181 where
182 S: INSString,
183 {
184 unsafe { msg_send![self.m_self(), setString: string] }
185 }
186}
187
188impl INSString for NSMutableString {}
189
190impl Default for NSMutableString {
191 fn default() -> Self {
192 Self::m_string()
193 }
194}
195
196impl PartialEq for NSMutableString {
197 fn eq(&self, other: &NSMutableString) -> bool {
198 self.m_localized_compare(other.clone()) == NSComparisonResult::OrderedSame
199 }
200}
201
202impl PartialEq<&str> for NSMutableString {
203 fn eq(&self, other: &&str) -> bool {
204 self.m_localized_compare(NSString::from(*other)) == NSComparisonResult::OrderedSame
205 }
206}
207
208impl From<NSString> for NSMutableString {
209 fn from(string: NSString) -> Self {
210 unsafe {
211 let ptr: id = msg_send![NSString::m_class(), alloc];
212 let ptr: id = msg_send![ptr, initWithString: string];
213 NSMutableString::from_id(ptr)
214 }
215 }
216}
217
218#[cfg(test)]
219mod tests {
220
221 use crate::foundation::{string::Encoding, LatinToKatakana, NSStringCompareOptions};
222
223 use super::*;
224
225 #[test]
226 fn test_tm_string_with_capacity() {
227 let string = NSMutableString::string_with_capacity(10);
228 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 0);
229 }
230
231 #[test]
232 fn test_im_append_string() {
233 let mut string = NSMutableString::string_with_capacity(10);
234 string.append_string(NSString::from("Hello"));
235 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
236 }
237
238 #[test]
239 fn test_im_apply_transform_reverse_range_updated_range() {
240 let mut string = NSMutableString::string_with_capacity(10);
241 string.append_string(NSString::from("Hello"));
242 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
243 assert!(string.m_apply_transform_reverse_range_updated_range(
244 unsafe { LatinToKatakana },
245 false,
246 (0..5).into(),
247 (0..5).into()
248 ));
249 }
250
251 #[test]
252 fn test_im_delete_characters_in_range() {
253 let mut string = NSMutableString::string_with_capacity(10);
254 string.append_string(NSString::from("Hello"));
255 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
256 string.m_delete_characters_in_range((0..5).into());
257 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 0);
258 }
259
260 #[test]
261 fn test_im_insert_string_at_index() {
262 let mut string = NSMutableString::string_with_capacity(10);
263 string.append_string(NSString::from("Hello"));
264 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
265 string.m_insert_string_at_index(NSString::from("World"), 0);
266 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 10);
267 }
268
269 #[test]
270 fn test_im_replace_characters_in_range_with_string() {
271 let mut string = NSMutableString::string_with_capacity(10);
272 string.append_string(NSString::from("Hello"));
273 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
274 string.m_replace_characters_in_range_with_string((0..5).into(), NSString::from("World"));
275 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
276 }
277
278 #[test]
279 fn test_im_replace_occurrences_of_string_with_string_options_range() {
280 let mut string = NSMutableString::string_with_capacity(10);
281 string.append_string(NSString::from("Hello"));
282 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
283 assert_eq!(
284 string.m_replace_occurrences_of_string_with_string_options_range(
285 NSString::from("Hello"),
286 NSString::from("World"),
287 NSStringCompareOptions::CaseInsensitive,
288 (0..5).into()
289 ),
290 1
291 );
292 }
293
294 #[test]
295 fn test_im_set_string() {
296 let mut string = NSMutableString::string_with_capacity(10);
297 string.append_string(NSString::from("Hello"));
298 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
299 string.set_string(NSString::from("World"));
300 assert_eq!(string.m_length_of_bytes_using_encoding(Encoding::UTF8), 5);
301 }
302}