objc2_foundation/
lib.rs

1//! # Bindings to the `Foundation` framework
2//!
3//! See [Apple's docs][apple-doc] and [the general docs on framework crates][framework-crates] for more information.
4//!
5//! [apple-doc]: https://developer.apple.com/documentation/foundation/
6//! [framework-crates]: https://docs.rs/objc2/latest/objc2/topics/about_generated/index.html
7//!
8//! This is the [`std`] equivalent for Objective-C, containing essential data
9//! types, collections, and operating-system services.
10//!
11//!
12//! ## Rust vs. Objective-C types
13//!
14//! A quick overview of some types you will encounter often in Objective-C,
15//! and their approximate Rust equivalent.
16//!
17//! | Objective-C                  | (approximately) equivalent Rust               |
18//! | ---------------------------- | --------------------------------------------- |
19//! | `NSData*`                    | `Rc<[u8]>`                                    |
20//! | `NSMutableData*`             | `Rc<Cell<Vec<u8>>>`                           |
21//! | `NSString*`                  | `Rc<str>`                                     |
22//! | `NSMutableString*`           | `Rc<Cell<String>>`                            |
23//! | `NSValue*`                   | `Rc<dyn Any>`                                 |
24//! | `NSNumber*`                  | `Arc<enum { I8(i8), U8(u8), I16(i16), ... }>` |
25//! | `NSError*`                   | `Arc<dyn Error + Send + Sync>`                |
26//! | `NSException*`               | `Arc<dyn Error + Send + Sync>`                |
27//! | `NSRange`                    | `ops::Range<usize>`                           |
28//! | `NSComparisonResult`         | `cmp::Ordering`                               |
29//! | `NSEnumerator<T>*`           | `Rc<dyn Iterator<Item = Retained<T>>>`        |
30//! | `NSCopying*`                 | `Rc<dyn Clone>`                               |
31//! | `NSArray<T>*`                | `Rc<[Retained<T>]>`                           |
32//! | `NSMutableArray<T>*`         | `Rc<Cell<Vec<Retained<T>>>>`                  |
33//! | `NSDictionary<K, V>*`        | `Rc<HashMap<Retained<K>, Retained<V>>>`       |
34//! | `NSMutableDictionary<K, V>*` | `Rc<Cell<HashMap<Retained<K>, Retained<V>>>>` |
35//!
36//! Note, in particular, that all "Mutable" variants use interior mutability,
37//! and that some things are thread-safe (`Arc`), while others are not (`Rc`).
38//!
39//!
40//! ## Examples
41//!
42//! Basic usage of a few Foundation types.
43//!
44//! ```console
45//! $ cargo add objc2-foundation
46//! ```
47//!
48#![cfg_attr(
49    all(
50        feature = "NSObject",
51        feature = "NSString",
52        feature = "NSArray",
53        feature = "NSDictionary",
54        feature = "NSEnumerator"
55    ),
56    doc = "```"
57)]
58#![cfg_attr(
59    not(all(
60        feature = "NSObject",
61        feature = "NSString",
62        feature = "NSArray",
63        feature = "NSDictionary",
64        feature = "NSEnumerator"
65    )),
66    doc = "```ignore"
67)]
68//! use objc2_foundation::{ns_string, NSArray, NSDictionary, NSObject};
69//!
70//! // Create and compare NSObjects
71//! let obj = NSObject::new();
72//! #[allow(clippy::eq_op)]
73//! {
74//!     println!("{obj:?} == {obj:?}? {:?}", obj == obj);
75//! }
76//!
77//! let obj2 = NSObject::new();
78//! println!("{obj:?} == {obj2:?}? {:?}", obj == obj2);
79//!
80//! // Create an NSArray from a Vec
81//! let objs = vec![obj, obj2];
82//! let array = NSArray::from_retained_slice(&objs);
83//! for obj in array.iter() {
84//!     println!("{obj:?}");
85//! }
86//! println!("{}", array.len());
87//!
88//! // Turn the NSArray back into a Vec
89//! let mut objs = array.to_vec();
90//! let obj = objs.pop().unwrap();
91//!
92//! // Create a static NSString
93//! let string = ns_string!("Hello, world!");
94//! // And use the `ToString` implementation to convert it into a string
95//! let _s = string.to_string();
96//! // Or use the `Display` implementation directly
97//! println!("{string}");
98//!
99//! // Create a dictionary mapping strings to objects
100//! let keys = &[string];
101//! let objects = &[&*obj];
102//! let dict = NSDictionary::from_slices(keys, objects);
103//! println!("{:?}", dict.objectForKey(string));
104//! println!("{}", dict.len());
105//! ```
106#![no_std]
107#![cfg_attr(feature = "unstable-darwin-objc", feature(darwin_objc))]
108#![cfg_attr(docsrs, feature(doc_cfg))]
109// Update in Cargo.toml as well.
110#![doc(html_root_url = "https://docs.rs/objc2-foundation/0.3.2")]
111#![allow(non_snake_case)]
112#![recursion_limit = "512"]
113
114#[cfg(not(feature = "alloc"))]
115compile_error!("The `alloc` feature currently must be enabled.");
116
117extern crate alloc;
118
119#[cfg(feature = "std")]
120extern crate std;
121
122#[doc(hidden)]
123pub mod __ns_macro_helpers;
124#[cfg(feature = "NSEnumerator")]
125#[macro_use]
126mod iter;
127#[cfg(feature = "NSArray")]
128pub mod array;
129#[cfg(feature = "NSAttributedString")]
130mod attributed_string;
131#[cfg(feature = "NSBundle")]
132mod bundle;
133#[cfg(feature = "NSObjCRuntime")]
134mod comparison_result;
135#[cfg(feature = "NSObject")]
136mod copying;
137#[cfg(feature = "NSData")]
138mod data;
139#[cfg(feature = "NSDecimal")]
140mod decimal;
141#[cfg(feature = "NSDictionary")]
142pub mod dictionary;
143#[cfg(feature = "NSEnumerator")]
144pub mod enumerator;
145#[cfg(feature = "NSError")]
146mod error;
147#[cfg(feature = "NSException")]
148mod exception;
149#[cfg(feature = "NSEnumerator")]
150mod fast_enumeration_state;
151mod generated;
152#[cfg(feature = "NSGeometry")]
153mod geometry;
154mod macros;
155mod ns_consumed;
156#[cfg(feature = "NSValue")]
157mod number;
158#[cfg(feature = "NSProcessInfo")]
159mod process_info;
160#[cfg(feature = "NSRange")]
161mod range;
162#[cfg(feature = "NSSet")]
163pub mod set;
164#[cfg(feature = "NSString")]
165mod string;
166#[cfg(test)]
167mod tests;
168#[cfg(feature = "NSThread")]
169mod thread;
170#[cfg(feature = "NSObject")]
171mod to_owned;
172#[cfg(feature = "NSURL")]
173mod url;
174#[cfg(feature = "NSUserDefaults")]
175mod user_defaults;
176mod util;
177#[cfg(feature = "NSUUID")]
178mod uuid;
179#[cfg(feature = "NSValue")]
180mod value;
181
182#[cfg(feature = "NSObjCRuntime")]
183pub use self::comparison_result::NSComparisonResult;
184#[cfg(feature = "NSObject")]
185pub use self::copying::{CopyingHelper, MutableCopyingHelper, NSCopying, NSMutableCopying};
186#[cfg(feature = "NSDecimal")]
187pub use self::decimal::NSDecimal;
188#[cfg(feature = "NSEnumerator")]
189pub use self::fast_enumeration_state::NSFastEnumerationState;
190#[allow(unused_imports, unreachable_pub)]
191pub use self::generated::*;
192#[cfg(feature = "NSGeometry")]
193pub use self::geometry::NSRectEdge;
194#[cfg(all(feature = "NSGeometry", feature = "objc2-core-foundation"))]
195pub use self::geometry::{NSPoint, NSRect, NSSize};
196#[cfg(feature = "NSMapTable")]
197pub use self::ns_consumed::NSFreeMapTable;
198#[cfg(feature = "NSRange")]
199pub use self::range::NSRange;
200#[cfg(feature = "NSThread")]
201pub use self::thread::*;
202
203// Available under Foundation, so makes sense here as well:
204// https://developer.apple.com/documentation/foundation/numbers_data_and_basic_values?language=objc
205pub use objc2::ffi::{NSInteger, NSUInteger};
206
207// Special types that are stored in `objc2`, but really belong here
208#[doc(inline)]
209#[cfg(feature = "NSZone")]
210pub use objc2::runtime::NSZone;
211#[doc(inline)]
212#[cfg(feature = "NSProxy")]
213pub use objc2::runtime::__NSProxy as NSProxy;
214pub use objc2::runtime::{NSObject, NSObjectProtocol};
215#[deprecated = "Moved to `objc2::MainThreadMarker`"]
216pub use objc2::MainThreadMarker;
217
218#[cfg_attr(feature = "gnustep-1-7", link(name = "gnustep-base", kind = "dylib"))]
219extern "C" {}
220
221// MacTypes.h
222#[allow(unused)]
223pub(crate) type Boolean = u8; // unsigned char
224#[allow(unused)]
225pub(crate) type FourCharCode = u32;
226#[allow(unused)]
227pub(crate) type OSType = FourCharCode;
228#[allow(unused)]
229pub(crate) type UTF32Char = u32; // Or maybe Rust's char?
230#[allow(unused)]
231#[cfg(target_pointer_width = "64")]
232pub(crate) type SRefCon = *mut core::ffi::c_void;
233#[allow(unused)]
234#[cfg(target_pointer_width = "32")]
235pub(crate) type SRefCon = i32;
236#[allow(unused)]
237pub(crate) type OSErr = i16;
238
239/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nstimeintervalsince1970?language=objc)
240#[allow(non_upper_case_globals)]
241#[cfg(feature = "NSDate")]
242pub const NSTimeIntervalSince1970: crate::NSTimeInterval = 978307200.0;
243
244/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlresponseunknownlength?language=objc)
245#[allow(non_upper_case_globals)]
246#[cfg(feature = "NSURLResponse")]
247pub const NSURLResponseUnknownLength: core::ffi::c_longlong = -1;