objc2_foundation/
string.rs1#[cfg(feature = "NSObjCRuntime")]
2use core::cmp;
3use core::ffi::c_void;
4use core::fmt;
5use core::ops::AddAssign;
6use core::panic::RefUnwindSafe;
7use core::panic::UnwindSafe;
8use core::str;
9
10use objc2::msg_send;
11use objc2::rc::{autoreleasepool_leaking, Allocated, AutoreleasePool, Retained};
12use objc2::runtime::__nsstring::{nsstring_len, nsstring_to_str, UTF8_ENCODING};
13use objc2::{AnyThread, Message};
14
15use crate::util;
16use crate::{NSMutableString, NSString};
17
18impl UnwindSafe for NSString {}
21impl RefUnwindSafe for NSString {}
22
23impl NSString {
24 #[doc(alias = "lengthOfBytesUsingEncoding")]
26 #[doc(alias = "lengthOfBytesUsingEncoding:")]
27 pub fn len(&self) -> usize {
28 unsafe { nsstring_len(self) }
30 }
31
32 #[doc(alias = "length")]
36 pub fn len_utf16(&self) -> usize {
37 self.length()
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.len() == 0
44 }
45
46 #[doc(alias = "UTF8String")]
96 pub unsafe fn to_str<'r, 's: 'r, 'p: 'r>(&'s self, pool: AutoreleasePool<'p>) -> &'r str {
97 unsafe { nsstring_to_str(self, pool) }
101 }
102
103 #[doc(alias = "initWithBytes")]
111 #[doc(alias = "initWithBytes:length:encoding:")]
112 #[allow(clippy::should_implement_trait)] pub fn from_str(string: &str) -> Retained<Self> {
114 unsafe { init_with_str(Self::alloc(), string) }
115 }
116
117 }
119
120impl NSMutableString {
121 #[doc(alias = "initWithBytes:length:encoding:")]
123 #[allow(clippy::should_implement_trait)] pub fn from_str(string: &str) -> Retained<Self> {
125 unsafe { init_with_str(Self::alloc(), string) }
126 }
127}
128
129unsafe fn init_with_str<T: Message>(obj: Allocated<T>, string: &str) -> Retained<T> {
130 let bytes: *const c_void = string.as_ptr().cast();
131 unsafe {
134 msg_send![
135 obj,
136 initWithBytes: bytes,
137 length: string.len(),
138 encoding: UTF8_ENCODING,
139 ]
140 }
141}
142
143impl PartialEq<NSString> for NSMutableString {
144 #[inline]
145 fn eq(&self, other: &NSString) -> bool {
146 PartialEq::eq(&**self, other)
147 }
148}
149
150impl PartialEq<NSMutableString> for NSString {
151 #[inline]
152 fn eq(&self, other: &NSMutableString) -> bool {
153 PartialEq::eq(self, &**other)
154 }
155}
156
157#[cfg(feature = "NSObjCRuntime")]
158impl PartialOrd for NSString {
159 #[inline]
160 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
161 Some(self.cmp(other))
162 }
163}
164
165#[cfg(feature = "NSObjCRuntime")]
166impl Ord for NSString {
167 fn cmp(&self, other: &Self) -> cmp::Ordering {
168 self.compare(other).into()
169 }
170}
171
172#[cfg(feature = "NSObjCRuntime")]
173impl PartialOrd for NSMutableString {
174 #[inline]
175 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
176 Some(self.cmp(other))
177 }
178}
179
180#[cfg(feature = "NSObjCRuntime")]
181impl PartialOrd<NSString> for NSMutableString {
182 #[inline]
183 fn partial_cmp(&self, other: &NSString) -> Option<cmp::Ordering> {
184 PartialOrd::partial_cmp(&**self, other)
185 }
186}
187
188#[cfg(feature = "NSObjCRuntime")]
189impl PartialOrd<NSMutableString> for NSString {
190 #[inline]
191 fn partial_cmp(&self, other: &NSMutableString) -> Option<cmp::Ordering> {
192 PartialOrd::partial_cmp(self, &**other)
193 }
194}
195
196#[cfg(feature = "NSObjCRuntime")]
197impl Ord for NSMutableString {
198 #[inline]
199 fn cmp(&self, other: &Self) -> cmp::Ordering {
200 Ord::cmp(&**self, &**other)
201 }
202}
203
204impl AddAssign<&NSString> for &NSMutableString {
209 #[inline]
210 fn add_assign(&mut self, other: &NSString) {
211 self.appendString(other);
212 }
213}
214
215impl fmt::Display for NSString {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 unsafe { util::display_string(self, f) }
219 }
220}
221
222impl fmt::Debug for NSString {
223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224 autoreleasepool_leaking(|pool| fmt::Debug::fmt(unsafe { nsstring_to_str(self, pool) }, f))
229 }
230}
231
232impl fmt::Display for NSMutableString {
233 #[inline]
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 fmt::Display::fmt(&**self, f)
236 }
237}
238
239impl fmt::Write for &NSMutableString {
240 fn write_str(&mut self, s: &str) -> fmt::Result {
241 let nsstring = NSString::from_str(s);
242 self.appendString(&nsstring);
243 Ok(())
244 }
245}