diff --git a/Cargo.toml b/Cargo.toml index 398cf0ca7..492aa25bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "objc-sys", "objc2-encode", "objc2-foundation", + "objc2-foundation-sys", "objc2-proc-macros", "block2", "block-sys", diff --git a/objc2-foundation-sys/Cargo.toml b/objc2-foundation-sys/Cargo.toml new file mode 100644 index 000000000..1ea4a2ef8 --- /dev/null +++ b/objc2-foundation-sys/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "objc2-foundation-sys" +version = "0.0.1" # Remember to update html_root_url in lib.rs +authors = ["Mads Marquart "] +edition = "2021" + +# TODO: More metadata + +[features] +default = ["std", "apple"] + +std = ["alloc", "objc2/std"] +alloc = ["objc2/alloc"] + +apple = ["objc2/apple"] +gnustep-1-7 = ["objc2/gnustep-1-7"] +gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8"] +gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9"] +gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0"] +gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1"] + +[dependencies] +objc2 = { path = "../objc2", default-features = false } + +[package.metadata.docs.rs] +default-target = "x86_64-apple-darwin" +features = ["block"] + +targets = [ + # MacOS + "x86_64-apple-darwin", + "aarch64-apple-darwin", + # "i686-apple-darwin", + # iOS + "aarch64-apple-ios", + "x86_64-apple-ios", + # "armv7-apple-ios", + # "i386-apple-ios", + # GNUStep + "x86_64-unknown-linux-gnu", + "i686-unknown-linux-gnu", + # Windows + "x86_64-pc-windows-msvc", +] + diff --git a/objc2-foundation-sys/src/generated.rs b/objc2-foundation-sys/src/generated.rs new file mode 100644 index 000000000..f325eb46f --- /dev/null +++ b/objc2-foundation-sys/src/generated.rs @@ -0,0 +1,236 @@ +//! Example of what I would like `bindgen` to be able to generate. + +use crate::NSString; +use objc2::ffi::NSUInteger; +use objc2::rc::{Allocated, Id, Unknown}; +use objc2::runtime::{Bool, Class, Imp, Object, Protocol, Sel}; +use objc2::{class, msg_send, msg_send_id, Encoding, Message, RefEncode}; + +pub type NSInvocation = NSObject; +pub type NSMethodSignature = NSObject; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _NSZone { + _unused: [u8; 0], +} + +unsafe impl RefEncode for _NSZone { + const ENCODING_REF: Encoding<'static> = Encoding::Unknown; // TODO +} + +#[repr(transparent)] +pub struct NSObject(Object); + +unsafe impl Message for NSObject {} +unsafe impl RefEncode for NSObject { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} + +impl std::ops::Deref for NSObject { + type Target = Object; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl std::ops::DerefMut for NSObject { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl NSObject { + // alloc family + + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSObject), alloc] + } + pub unsafe fn allocWithZone_(zone: *mut _NSZone) -> Option, Unknown>> { + msg_send_id![class!(NSObject), allocWithZone: zone] + } + + // init family + + pub unsafe fn init(this: Option, Unknown>>) -> Option> { + msg_send_id![this, init] + } + + // TODO + pub unsafe fn dealloc(&mut self) { + msg_send![self, dealloc] + } + // TODO + pub unsafe fn finalize(&self) { + msg_send![self, finalize] + } + + // copy family + + pub unsafe fn copy(&self) -> Option> { + msg_send_id![self, copy] + } + pub unsafe fn copyWithZone_(zone: *mut _NSZone) -> Option> { + msg_send_id![class!(NSObject), copyWithZone: zone] + } + pub unsafe fn mutableCopy(&self) -> Option> { + msg_send_id![self, mutableCopy] + } + pub unsafe fn mutableCopyWithZone_(zone: *mut _NSZone) -> Option> { + msg_send_id![class!(NSObject), mutableCopyWithZone: zone] + } + + pub unsafe fn methodForSelector_(&self, aSelector: Sel) -> Option { + msg_send![self, methodForSelector: aSelector] + } + pub unsafe fn doesNotRecognizeSelector_(&self, aSelector: Sel) { + msg_send![self, doesNotRecognizeSelector: aSelector] + } + pub unsafe fn forwardingTargetForSelector_( + &self, + aSelector: Sel, + ) -> Option> { + msg_send_id![self, forwardingTargetForSelector: aSelector] + } + pub unsafe fn forwardInvocation_(&self, anInvocation: *const NSInvocation) { + msg_send![self, forwardInvocation: anInvocation] + } + pub unsafe fn methodSignatureForSelector_( + &self, + aSelector: Sel, + ) -> Option> { + msg_send_id![self, methodSignatureForSelector: aSelector] + } + pub unsafe fn allowsWeakReference(&self) -> Bool { + msg_send![self, allowsWeakReference] + } + pub unsafe fn retainWeakReference(&self) -> Bool { + msg_send![self, retainWeakReference] + } + pub unsafe fn load() { + msg_send![class!(NSObject), load] + } + pub unsafe fn initialize() { + msg_send![class!(NSObject), initialize] + } + pub unsafe fn new() -> Option> { + msg_send_id![class!(NSObject), new] + } + pub unsafe fn instancesRespondToSelector_(aSelector: Sel) -> Bool { + msg_send![class!(NSObject), instancesRespondToSelector: aSelector] + } + pub unsafe fn class_conformsToProtocol_(protocol: &Protocol) -> Bool { + msg_send![class!(NSObject), conformsToProtocol: protocol] + } + pub unsafe fn instanceMethodForSelector_(aSelector: Sel) -> Option { + msg_send![class!(NSObject), instanceMethodForSelector: aSelector] + } + pub unsafe fn instanceMethodSignatureForSelector_( + aSelector: Sel, + ) -> Option> { + msg_send_id![ + class!(NSObject), + instanceMethodSignatureForSelector: aSelector, + ] + } + pub unsafe fn isSubclassOfClass_(aClass: &Class) -> Bool { + msg_send![class!(NSObject), isSubclassOfClass: aClass] + } + pub unsafe fn resolveClassMethod_(sel: Sel) -> Bool { + msg_send![class!(NSObject), resolveClassMethod: sel] + } + pub unsafe fn resolveInstanceMethod_(sel: Sel) -> Bool { + msg_send![class!(NSObject), resolveInstanceMethod: sel] + } + pub unsafe fn class_hash() -> NSUInteger { + msg_send![class!(NSObject), hash] + } + pub unsafe fn class_superclass<'a>() -> &'a Class { + msg_send![class!(NSObject), superclass] + } + pub unsafe fn class_class<'a>() -> Option<&'a Class> { + msg_send![class!(NSObject), class] + } + pub unsafe fn class_description() -> Option> { + msg_send_id![class!(NSObject), description] + } + pub unsafe fn class_debugDescription() -> Option> { + msg_send_id![class!(NSObject), debugDescription] + } + + pub unsafe fn isEqual_(&self, object: &Self) -> Bool { + msg_send![self, isEqual: object] + } + pub unsafe fn self_(&self) -> Option> { + msg_send_id![self, self] + } + pub unsafe fn performSelector_(&self, aSelector: Sel) -> Option> { + msg_send_id![self, performSelector: aSelector] + } + pub unsafe fn performSelector_withObject_( + &self, + aSelector: Sel, + object: *const Object, + ) -> Option> { + msg_send_id![self, performSelector: aSelector, withObject: object] + } + pub unsafe fn performSelector_withObject_withObject_( + &self, + aSelector: Sel, + object1: *const Object, + object2: *const Object, + ) -> Option> { + msg_send_id![ + self, + performSelector: aSelector, + withObject: object1, + withObject: object2, + ] + } + pub unsafe fn isProxy(&self) -> Bool { + msg_send![self, isProxy] + } + pub unsafe fn isKindOfClass_(&self, aClass: &Class) -> Bool { + msg_send![self, isKindOfClass: aClass] + } + pub unsafe fn isMemberOfClass_(&self, aClass: &Class) -> Bool { + msg_send![self, isMemberOfClass: aClass] + } + pub unsafe fn conformsToProtocol_(&self, aProtocol: &Protocol) -> Bool { + msg_send![self, conformsToProtocol: aProtocol] + } + pub unsafe fn respondsToSelector_(&self, aSelector: Sel) -> Bool { + msg_send![self, respondsToSelector: aSelector] + } + // pub unsafe fn retain(&self) -> Option> { + // msg_send_id![self, retain] + // } + // pub unsafe fn release(&self) { + // msg_send![self, release] + // } + // pub unsafe fn autorelease(&self) -> Option> { + // msg_send_id![self, autorelease] + // } + pub unsafe fn retainCount(&self) -> NSUInteger { + msg_send![self, retainCount] + } + pub unsafe fn zone(&self) -> *mut _NSZone { + msg_send![self, zone] + } + pub unsafe fn hash(&self) -> NSUInteger { + msg_send![self, hash] + } + pub unsafe fn class(&self) -> Option<&Class> { + msg_send![self, class] + } + pub unsafe fn superclass(&self) -> Option<&Class> { + msg_send![self, superclass] + } + pub unsafe fn description(&self) -> Option> { + msg_send_id![self, description] + } + pub unsafe fn debugDescription(&self) -> Option> { + msg_send_id![self, debugDescription] + } +} diff --git a/objc2-foundation-sys/src/generated_nsstring.rs b/objc2-foundation-sys/src/generated_nsstring.rs new file mode 100644 index 000000000..8b3dc1e86 --- /dev/null +++ b/objc2-foundation-sys/src/generated_nsstring.rs @@ -0,0 +1,1214 @@ +//! Example of what I would like `bindgen` to be able to generate for NSString + +use core::ptr::NonNull; + +use std::os::raw::{c_char, c_int, c_longlong, c_schar, c_ulong, c_ushort, c_void}; + +use objc2::ffi::{NSInteger, NSUInteger}; +use objc2::rc::{Allocated, Id, Unknown}; +use objc2::runtime::{Bool, Object}; +use objc2::{class, msg_send, msg_send_id, Encoding, Message, RefEncode}; + +use crate::{NSData, NSObject}; + +pub type NSRange = [NSUInteger; 2]; +pub type NSComparisonResult = NSInteger; + +pub type NSCoder = NSObject; +pub type NSLocale = NSObject; +pub type NSError = NSObject; +pub type NSDictionary = NSObject; +pub type NSCharacterSet = NSObject; +pub type NSURL = NSObject; + +pub type unichar = c_ushort; + +pub const NSStringCompareOptions_NSCaseInsensitiveSearch: NSStringCompareOptions = 1; +pub const NSStringCompareOptions_NSLiteralSearch: NSStringCompareOptions = 2; +pub const NSStringCompareOptions_NSBackwardsSearch: NSStringCompareOptions = 4; +pub const NSStringCompareOptions_NSAnchoredSearch: NSStringCompareOptions = 8; +pub const NSStringCompareOptions_NSNumericSearch: NSStringCompareOptions = 64; +pub const NSStringCompareOptions_NSDiacriticInsensitiveSearch: NSStringCompareOptions = 128; +pub const NSStringCompareOptions_NSWidthInsensitiveSearch: NSStringCompareOptions = 256; +pub const NSStringCompareOptions_NSForcedOrderingSearch: NSStringCompareOptions = 512; +pub const NSStringCompareOptions_NSRegularExpressionSearch: NSStringCompareOptions = 1024; +pub type NSStringCompareOptions = NSUInteger; +pub type NSStringEncoding = NSUInteger; +pub const NSASCIIStringEncoding: NSStringEncoding = 1; +pub const NSNEXTSTEPStringEncoding: NSStringEncoding = 2; +pub const NSJapaneseEUCStringEncoding: NSStringEncoding = 3; +pub const NSUTF8StringEncoding: NSStringEncoding = 4; +pub const NSISOLatin1StringEncoding: NSStringEncoding = 5; +pub const NSSymbolStringEncoding: NSStringEncoding = 6; +pub const NSNonLossyASCIIStringEncoding: NSStringEncoding = 7; +pub const NSShiftJISStringEncoding: NSStringEncoding = 8; +pub const NSISOLatin2StringEncoding: NSStringEncoding = 9; +pub const NSUnicodeStringEncoding: NSStringEncoding = 10; +pub const NSWindowsCP1251StringEncoding: NSStringEncoding = 11; +pub const NSWindowsCP1252StringEncoding: NSStringEncoding = 12; +pub const NSWindowsCP1253StringEncoding: NSStringEncoding = 13; +pub const NSWindowsCP1254StringEncoding: NSStringEncoding = 14; +pub const NSWindowsCP1250StringEncoding: NSStringEncoding = 15; +pub const NSISO2022JPStringEncoding: NSStringEncoding = 21; +pub const NSMacOSRomanStringEncoding: NSStringEncoding = 30; +pub const NSUTF16StringEncoding: NSStringEncoding = 10; +pub const NSUTF16BigEndianStringEncoding: NSStringEncoding = 2415919360; +pub const NSUTF16LittleEndianStringEncoding: NSStringEncoding = 2483028224; +pub const NSUTF32StringEncoding: NSStringEncoding = 2348810496; +pub const NSUTF32BigEndianStringEncoding: NSStringEncoding = 2550137088; +pub const NSUTF32LittleEndianStringEncoding: NSStringEncoding = 2617245952; +pub type _bindgen_ty_10 = NSStringEncoding; +pub const NSStringEncodingConversionOptions_NSStringEncodingConversionAllowLossy: + NSStringEncodingConversionOptions = 1; +pub const NSStringEncodingConversionOptions_NSStringEncodingConversionExternalRepresentation: + NSStringEncodingConversionOptions = 2; +pub type NSStringEncodingConversionOptions = NSUInteger; + +#[repr(transparent)] +pub struct NSString(NSObject); +impl core::ops::Deref for NSString { + type Target = NSObject; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSString { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +unsafe impl Message for NSString {} +unsafe impl RefEncode for NSString { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSString { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSString), alloc] + } +} +impl NSString { + pub unsafe fn characterAtIndex_(&self, index: NSUInteger) -> unichar { + msg_send![self, characterAtIndex: index] + } + pub unsafe fn init(this: Option, Unknown>>) -> Id { + // Marked nonnull + msg_send_id![this, init].unwrap_unchecked() + } + pub unsafe fn initWithCoder_( + this: Option, Unknown>>, + coder: &NSCoder, + ) -> Option> { + msg_send_id![this, initWithCoder: coder] + } + pub unsafe fn length(&self) -> NSUInteger { + msg_send![self, length] + } +} +#[doc = " NSStringExtensionMethods"] +impl NSString { + pub unsafe fn substringFromIndex_(&self, from: NSUInteger) -> Id { + msg_send_id![self, substringFromIndex: from].unwrap_unchecked() + } + pub unsafe fn substringToIndex_(&self, to: NSUInteger) -> Id { + msg_send_id![self, substringToIndex: to].unwrap_unchecked() + } + pub unsafe fn substringWithRange_(&self, range: NSRange) -> Id { + msg_send_id![self, substringWithRange: range].unwrap_unchecked() + } + pub unsafe fn getCharacters_range_(&self, buffer: NonNull, range: NSRange) { + msg_send![self, getCharacters: buffer, range: range] + } + pub unsafe fn compare_(&self, string: NonNull) -> NSComparisonResult { + msg_send![self, compare: string] + } + pub unsafe fn compare_options_( + &self, + string: NonNull, + mask: NSStringCompareOptions, + ) -> NSComparisonResult { + msg_send![self, compare: string, options: mask] + } + pub unsafe fn compare_options_range_( + &self, + string: NonNull, + mask: NSStringCompareOptions, + rangeOfReceiverToCompare: NSRange, + ) -> NSComparisonResult { + msg_send![ + self, + compare: string, + options: mask, + range: rangeOfReceiverToCompare + ] + } + pub unsafe fn compare_options_range_locale_( + &self, + string: NonNull, + mask: NSStringCompareOptions, + rangeOfReceiverToCompare: NSRange, + locale: *mut Object, + ) -> NSComparisonResult { + msg_send![ + self, + compare: string, + options: mask, + range: rangeOfReceiverToCompare, + locale: locale + ] + } + pub unsafe fn caseInsensitiveCompare_(&self, string: NonNull) -> NSComparisonResult { + msg_send![self, caseInsensitiveCompare: string] + } + pub unsafe fn localizedCompare_(&self, string: NonNull) -> NSComparisonResult { + msg_send![self, localizedCompare: string] + } + pub unsafe fn localizedCaseInsensitiveCompare_( + &self, + string: NonNull, + ) -> NSComparisonResult { + msg_send![self, localizedCaseInsensitiveCompare: string] + } + pub unsafe fn localizedStandardCompare_( + &self, + string: NonNull, + ) -> NSComparisonResult { + msg_send![self, localizedStandardCompare: string] + } + pub unsafe fn isEqualToString_(&self, aString: NonNull) -> Bool { + msg_send![self, isEqualToString: aString] + } + pub unsafe fn hasPrefix_(&self, str_: NonNull) -> Bool { + msg_send![self, hasPrefix: str_] + } + pub unsafe fn hasSuffix_(&self, str_: NonNull) -> Bool { + msg_send![self, hasSuffix: str_] + } + pub unsafe fn commonPrefixWithString_options_( + &self, + str_: NonNull, + mask: NSStringCompareOptions, + ) -> Id { + msg_send_id![self, commonPrefixWithString: str_, options: mask].unwrap_unchecked() + } + pub unsafe fn containsString_(&self, str_: NonNull) -> Bool { + msg_send![self, containsString: str_] + } + pub unsafe fn localizedCaseInsensitiveContainsString_(&self, str_: NonNull) -> Bool { + msg_send![self, localizedCaseInsensitiveContainsString: str_] + } + pub unsafe fn localizedStandardContainsString_(&self, str_: NonNull) -> Bool { + msg_send![self, localizedStandardContainsString: str_] + } + pub unsafe fn localizedStandardRangeOfString_(&self, str_: NonNull) -> NSRange { + msg_send![self, localizedStandardRangeOfString: str_] + } + pub unsafe fn rangeOfString_(&self, searchString: NonNull) -> NSRange { + msg_send![self, rangeOfString: searchString] + } + pub unsafe fn rangeOfString_options_( + &self, + searchString: NonNull, + mask: NSStringCompareOptions, + ) -> NSRange { + msg_send![self, rangeOfString: searchString, options: mask] + } + pub unsafe fn rangeOfString_options_range_( + &self, + searchString: NonNull, + mask: NSStringCompareOptions, + rangeOfReceiverToSearch: NSRange, + ) -> NSRange { + msg_send![ + self, + rangeOfString: searchString, + options: mask, + range: rangeOfReceiverToSearch + ] + } + pub unsafe fn rangeOfString_options_range_locale_( + &self, + searchString: NonNull, + mask: NSStringCompareOptions, + rangeOfReceiverToSearch: NSRange, + locale: *mut NSLocale, + ) -> NSRange { + msg_send![ + self, + rangeOfString: searchString, + options: mask, + range: rangeOfReceiverToSearch, + locale: locale + ] + } + pub unsafe fn rangeOfCharacterFromSet_(&self, searchSet: NonNull) -> NSRange { + msg_send![self, rangeOfCharacterFromSet: searchSet] + } + pub unsafe fn rangeOfCharacterFromSet_options_( + &self, + searchSet: NonNull, + mask: NSStringCompareOptions, + ) -> NSRange { + msg_send![self, rangeOfCharacterFromSet: searchSet, options: mask] + } + pub unsafe fn rangeOfCharacterFromSet_options_range_( + &self, + searchSet: NonNull, + mask: NSStringCompareOptions, + rangeOfReceiverToSearch: NSRange, + ) -> NSRange { + msg_send![ + self, + rangeOfCharacterFromSet: searchSet, + options: mask, + range: rangeOfReceiverToSearch + ] + } + pub unsafe fn rangeOfComposedCharacterSequenceAtIndex_(&self, index: NSUInteger) -> NSRange { + msg_send![self, rangeOfComposedCharacterSequenceAtIndex: index] + } + pub unsafe fn rangeOfComposedCharacterSequencesForRange_(&self, range: NSRange) -> NSRange { + msg_send![self, rangeOfComposedCharacterSequencesForRange: range] + } + pub unsafe fn stringByAppendingString_( + &self, + aString: NonNull, + ) -> Id { + msg_send_id![self, stringByAppendingString: aString].unwrap_unchecked() + } + pub unsafe fn stringByAppendingFormat_( + &self, + format: NonNull, + ) -> Id { + msg_send_id![self, stringByAppendingFormat: format].unwrap_unchecked() + } + pub unsafe fn uppercaseStringWithLocale_( + &self, + locale: *mut NSLocale, + ) -> Id { + msg_send_id![self, uppercaseStringWithLocale: locale].unwrap_unchecked() + } + pub unsafe fn lowercaseStringWithLocale_( + &self, + locale: *mut NSLocale, + ) -> Id { + msg_send_id![self, lowercaseStringWithLocale: locale].unwrap_unchecked() + } + pub unsafe fn capitalizedStringWithLocale_( + &self, + locale: *mut NSLocale, + ) -> Id { + msg_send_id![self, capitalizedStringWithLocale: locale].unwrap_unchecked() + } + pub unsafe fn getLineStart_end_contentsEnd_forRange_( + &self, + startPtr: *mut c_ulong, + lineEndPtr: *mut c_ulong, + contentsEndPtr: *mut c_ulong, + range: NSRange, + ) { + msg_send![ + self, + getLineStart: startPtr, + end: lineEndPtr, + contentsEnd: contentsEndPtr, + forRange: range + ] + } + pub unsafe fn lineRangeForRange_(&self, range: NSRange) -> NSRange { + msg_send![self, lineRangeForRange: range] + } + pub unsafe fn getParagraphStart_end_contentsEnd_forRange_( + &self, + startPtr: *mut c_ulong, + parEndPtr: *mut c_ulong, + contentsEndPtr: *mut c_ulong, + range: NSRange, + ) { + msg_send![ + self, + getParagraphStart: startPtr, + end: parEndPtr, + contentsEnd: contentsEndPtr, + forRange: range + ] + } + pub unsafe fn paragraphRangeForRange_(&self, range: NSRange) -> NSRange { + msg_send![self, paragraphRangeForRange: range] + } + pub unsafe fn enumerateSubstringsInRange_options_usingBlock_( + &self, + range: NSRange, + opts: NSStringEnumerationOptions, + block: *mut c_void, + ) { + msg_send![ + self, + enumerateSubstringsInRange: range, + options: opts, + usingBlock: block + ] + } + pub unsafe fn enumerateLinesUsingBlock_(&self, block: *mut c_void) { + msg_send![self, enumerateLinesUsingBlock: block] + } + pub unsafe fn dataUsingEncoding_allowLossyConversion_( + &self, + encoding: NSStringEncoding, + lossy: Bool, + ) -> Id { + msg_send_id![ + self, + dataUsingEncoding: encoding, + allowLossyConversion: lossy + ] + .unwrap_unchecked() + } + pub unsafe fn dataUsingEncoding_(&self, encoding: NSStringEncoding) -> Id { + msg_send_id![self, dataUsingEncoding: encoding].unwrap_unchecked() + } + pub unsafe fn canBeConvertedToEncoding_(&self, encoding: NSStringEncoding) -> Bool { + msg_send![self, canBeConvertedToEncoding: encoding] + } + pub unsafe fn cStringUsingEncoding_(&self, encoding: NSStringEncoding) -> *const c_char { + msg_send![self, cStringUsingEncoding: encoding] + } + pub unsafe fn getCString_maxLength_encoding_( + &self, + buffer: *mut c_char, + maxBufferCount: NSUInteger, + encoding: NSStringEncoding, + ) -> Bool { + msg_send![ + self, + getCString: buffer, + maxLength: maxBufferCount, + encoding: encoding + ] + } + pub unsafe fn getBytes_maxLength_usedLength_encoding_options_range_remainingRange_( + &self, + buffer: *mut c_void, + maxBufferCount: NSUInteger, + usedBufferCount: *mut c_ulong, + encoding: NSStringEncoding, + options: NSStringEncodingConversionOptions, + range: NSRange, + leftover: *mut NSRange, + ) -> Bool { + msg_send![ + self, + getBytes: buffer, + maxLength: maxBufferCount, + usedLength: usedBufferCount, + encoding: encoding, + options: options, + range: range, + remainingRange: leftover, + ] + } + pub unsafe fn maximumLengthOfBytesUsingEncoding_(&self, enc: NSStringEncoding) -> NSUInteger { + msg_send![self, maximumLengthOfBytesUsingEncoding: enc] + } + pub unsafe fn lengthOfBytesUsingEncoding_(&self, enc: NSStringEncoding) -> NSUInteger { + msg_send![self, lengthOfBytesUsingEncoding: enc] + } + pub unsafe fn componentsSeparatedByString_( + &self, + separator: NonNull, + ) -> Option> { + msg_send_id![self, componentsSeparatedByString: separator] + } + pub unsafe fn componentsSeparatedByCharactersInSet_( + &self, + separator: NonNull, + ) -> Id { + msg_send_id![self, componentsSeparatedByCharactersInSet: separator].unwrap_unchecked() + } + pub unsafe fn stringByTrimmingCharactersInSet_( + &self, + set: NonNull, + ) -> Id { + msg_send_id![self, stringByTrimmingCharactersInSet: set].unwrap_unchecked() + } + pub unsafe fn stringByPaddingToLength_withString_startingAtIndex_( + &self, + newLength: NSUInteger, + padString: NonNull, + padIndex: NSUInteger, + ) -> Id { + msg_send_id![ + self, + stringByPaddingToLength: newLength, + withString: padString, + startingAtIndex: padIndex + ] + .unwrap_unchecked() + } + pub unsafe fn stringByFoldingWithOptions_locale_( + &self, + options: NSStringCompareOptions, + locale: *mut NSLocale, + ) -> Id { + msg_send_id![self, stringByFoldingWithOptions: options, locale: locale].unwrap_unchecked() + } + pub unsafe fn stringByReplacingOccurrencesOfString_withString_options_range_( + &self, + target: NonNull, + replacement: NonNull, + options: NSStringCompareOptions, + searchRange: NSRange, + ) -> Id { + msg_send_id![ + self, + stringByReplacingOccurrencesOfString: target, + withString: replacement, + options: options, + range: searchRange + ] + .unwrap_unchecked() + } + pub unsafe fn stringByReplacingOccurrencesOfString_withString_( + &self, + target: NonNull, + replacement: NonNull, + ) -> Id { + msg_send_id![ + self, + stringByReplacingOccurrencesOfString: target, + withString: replacement + ] + .unwrap_unchecked() + } + pub unsafe fn stringByReplacingCharactersInRange_withString_( + &self, + range: NSRange, + replacement: NonNull, + ) -> Id { + msg_send_id![ + self, + stringByReplacingCharactersInRange: range, + withString: replacement + ] + .unwrap_unchecked() + } + pub unsafe fn stringByApplyingTransform_reverse_( + &self, + transform: NonNull, + reverse: Bool, + ) -> Option> { + msg_send_id![self, stringByApplyingTransform: transform, reverse: reverse] + } + pub unsafe fn writeToURL_atomically_encoding_error_( + &self, + url: NonNull, + useAuxiliaryFile: Bool, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Bool { + msg_send![ + self, + writeToURL: url, + atomically: useAuxiliaryFile, + encoding: enc, + error: error + ] + } + pub unsafe fn writeToFile_atomically_encoding_error_( + &self, + path: NonNull, + useAuxiliaryFile: Bool, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Bool { + msg_send![ + self, + writeToFile: path, + atomically: useAuxiliaryFile, + encoding: enc, + error: error + ] + } + pub unsafe fn initWithCharactersNoCopy_length_freeWhenDone_( + this: Option, Unknown>>, + characters: *mut c_ushort, + length: NSUInteger, + freeBuffer: Bool, + ) -> Id { + msg_send_id![ + this, + initWithCharactersNoCopy: characters, + length: length, + freeWhenDone: freeBuffer, + ] + .unwrap_unchecked() + } + pub unsafe fn initWithCharacters_length_( + this: Option, Unknown>>, + characters: *const c_ushort, + length: NSUInteger, + ) -> Id { + msg_send_id![this, initWithCharacters: characters, length: length].unwrap_unchecked() + } + pub unsafe fn initWithUTF8String_( + this: Option, Unknown>>, + nullTerminatedCString: *const c_char, + ) -> Option> { + msg_send_id![this, initWithUTF8String: nullTerminatedCString] + } + pub unsafe fn initWithString_( + this: Option, Unknown>>, + aString: NonNull, + ) -> Id { + msg_send_id![this, initWithString: aString].unwrap_unchecked() + } + pub unsafe fn initWithFormat_( + this: Option, Unknown>>, + format: NonNull, + ) -> Id { + msg_send_id![this, initWithFormat: format].unwrap_unchecked() + } + // pub unsafe fn initWithFormat_arguments_( + // this: Id, + // format: NonNull, + // argList: *mut __va_list_tag, + // ) -> Id { + // let this = ManuallyDrop::new(this); + // msg_send_id![this, initWithFormat: format, arguments: argList] + // } + pub unsafe fn initWithFormat_locale_( + this: Option, Unknown>>, + format: NonNull, + locale: *mut Object, + ) -> Id { + msg_send_id![this, initWithFormat: format, locale: locale].unwrap_unchecked() + } + // pub unsafe fn initWithFormat_locale_arguments_( + // this: Id, + // format: NonNull, + // locale: *mut Object, + // argList: *mut __va_list_tag, + // ) -> Id { + // let this = ManuallyDrop::new(this); + // Id::new(msg_send![ + // this, + // initWithFormat: format, + // locale: locale, + // arguments: argList + // ]) + // } + pub unsafe fn initWithData_encoding_( + this: Option, Unknown>>, + data: NonNull, + encoding: NSStringEncoding, + ) -> Option> { + msg_send_id![this, initWithData: data, encoding: encoding] + } + pub unsafe fn initWithBytes_length_encoding_( + this: Option, Unknown>>, + bytes: *const c_void, + len: NSUInteger, + encoding: NSStringEncoding, + ) -> Option> { + msg_send_id![this, initWithBytes: bytes, length: len, encoding: encoding] + } + pub unsafe fn initWithBytesNoCopy_length_encoding_freeWhenDone_( + this: Option, Unknown>>, + bytes: *mut c_void, + len: NSUInteger, + encoding: NSStringEncoding, + freeBuffer: Bool, + ) -> Option> { + msg_send_id![ + this, + initWithBytesNoCopy: bytes, + length: len, + encoding: encoding, + freeWhenDone: freeBuffer + ] + } + pub unsafe fn initWithCString_encoding_( + this: Option, Unknown>>, + nullTerminatedCString: *const c_char, + encoding: NSStringEncoding, + ) -> Option> { + msg_send_id![ + this, + initWithCString: nullTerminatedCString, + encoding: encoding + ] + } + pub unsafe fn initWithContentsOfURL_encoding_error_( + this: Option, Unknown>>, + url: NonNull, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + this, + initWithContentsOfURL: url, + encoding: enc, + error: error + ] + } + pub unsafe fn initWithContentsOfFile_encoding_error_( + this: Option, Unknown>>, + path: NonNull, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + this, + initWithContentsOfFile: path, + encoding: enc, + error: error + ] + } + pub unsafe fn initWithContentsOfURL_usedEncoding_error_( + this: Option, Unknown>>, + url: NonNull, + enc: *mut c_ulong, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + this, + initWithContentsOfURL: url, + usedEncoding: enc, + error: error + ] + } + pub unsafe fn initWithContentsOfFile_usedEncoding_error_( + this: Option, Unknown>>, + path: NonNull, + enc: *mut c_ulong, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + this, + initWithContentsOfFile: path, + usedEncoding: enc, + error: error + ] + } + pub unsafe fn doubleValue(&self) -> f64 { + msg_send![self, doubleValue] + } + pub unsafe fn floatValue(&self) -> f32 { + msg_send![self, floatValue] + } + pub unsafe fn intValue(&self) -> c_int { + msg_send![self, intValue] + } + pub unsafe fn integerValue(&self) -> NSInteger { + msg_send![self, integerValue] + } + pub unsafe fn longLongValue(&self) -> c_longlong { + msg_send![self, longLongValue] + } + pub unsafe fn boolValue(&self) -> Bool { + msg_send![self, boolValue] + } + pub unsafe fn uppercaseString(&self) -> Id { + msg_send_id![self, uppercaseString].unwrap_unchecked() + } + pub unsafe fn lowercaseString(&self) -> Id { + msg_send_id![self, lowercaseString].unwrap_unchecked() + } + pub unsafe fn capitalizedString(&self) -> Id { + msg_send_id![self, capitalizedString].unwrap_unchecked() + } + pub unsafe fn localizedUppercaseString(&self) -> Id { + msg_send_id![self, localizedUppercaseString].unwrap_unchecked() + } + pub unsafe fn localizedLowercaseString(&self) -> Id { + msg_send_id![self, localizedLowercaseString].unwrap_unchecked() + } + pub unsafe fn localizedCapitalizedString(&self) -> Id { + msg_send_id![self, localizedCapitalizedString].unwrap_unchecked() + } + pub unsafe fn UTF8String(&self) -> *const c_char { + msg_send![self, UTF8String] + } + pub unsafe fn fastestEncoding(&self) -> NSStringEncoding { + msg_send![self, fastestEncoding] + } + pub unsafe fn smallestEncoding(&self) -> NSStringEncoding { + msg_send![self, smallestEncoding] + } + pub unsafe fn decomposedStringWithCanonicalMapping(&self) -> Id { + msg_send_id![self, decomposedStringWithCanonicalMapping].unwrap_unchecked() + } + pub unsafe fn precomposedStringWithCanonicalMapping(&self) -> Id { + msg_send_id![self, precomposedStringWithCanonicalMapping].unwrap_unchecked() + } + pub unsafe fn decomposedStringWithCompatibilityMapping(&self) -> Id { + msg_send_id![self, decomposedStringWithCompatibilityMapping].unwrap_unchecked() + } + pub unsafe fn precomposedStringWithCompatibilityMapping(&self) -> Id { + msg_send_id![self, precomposedStringWithCompatibilityMapping].unwrap_unchecked() + } + pub unsafe fn description(&self) -> Id { + msg_send_id![self, description].unwrap_unchecked() + } + pub unsafe fn hash(&self) -> NSUInteger { + msg_send![self, hash] + } + pub unsafe fn localizedNameOfStringEncoding_( + encoding: NSStringEncoding, + ) -> Id { + msg_send_id![class!(NSString), localizedNameOfStringEncoding: encoding].unwrap_unchecked() + } + pub unsafe fn string() -> Id { + msg_send_id![class!(NSString), string].unwrap_unchecked() + } + pub unsafe fn stringWithString_(string: NonNull) -> Id { + msg_send_id![class!(NSString), stringWithString: string].unwrap_unchecked() + } + pub unsafe fn stringWithCharacters_length_( + characters: *const c_ushort, + length: NSUInteger, + ) -> Id { + msg_send_id![ + class!(NSString), + stringWithCharacters: characters, + length: length + ] + .unwrap_unchecked() + } + pub unsafe fn stringWithUTF8String_( + nullTerminatedCString: *const c_char, + ) -> Option> { + msg_send_id![ + class!(NSString), + stringWithUTF8String: nullTerminatedCString, + ] + } + pub unsafe fn stringWithFormat_(format: NonNull) -> Id { + msg_send_id![class!(NSString), stringWithFormat: format].unwrap_unchecked() + } + pub unsafe fn localizedStringWithFormat_(format: NonNull) -> Id { + msg_send_id![class!(NSString), localizedStringWithFormat: format].unwrap_unchecked() + } + pub unsafe fn stringWithCString_encoding_( + cString: *const c_char, + enc: NSStringEncoding, + ) -> Option> { + msg_send_id![class!(NSString), stringWithCString: cString, encoding: enc] + } + pub unsafe fn stringWithContentsOfURL_encoding_error_( + url: NonNull, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + class!(NSString), + stringWithContentsOfURL: url, + encoding: enc, + error: error + ] + } + pub unsafe fn stringWithContentsOfFile_encoding_error_( + path: NonNull, + enc: NSStringEncoding, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + class!(NSString), + stringWithContentsOfFile: path, + encoding: enc, + error: error + ] + } + pub unsafe fn stringWithContentsOfURL_usedEncoding_error_( + url: NonNull, + enc: *mut c_ulong, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + class!(NSString), + stringWithContentsOfURL: url, + usedEncoding: enc, + error: error + ] + } + pub unsafe fn stringWithContentsOfFile_usedEncoding_error_( + path: NonNull, + enc: *mut c_ulong, + error: *mut NSError, + ) -> Option> { + msg_send_id![ + class!(NSString), + stringWithContentsOfFile: path, + usedEncoding: enc, + error: error + ] + } + pub unsafe fn availableStringEncodings() -> *const c_ulong { + msg_send![class!(NSString), availableStringEncodings] + } + pub unsafe fn defaultCStringEncoding() -> NSStringEncoding { + msg_send![class!(NSString), defaultCStringEncoding] + } +} +pub const NSStringEnumerationOptions_NSStringEnumerationByLines: NSStringEnumerationOptions = 0; +pub const NSStringEnumerationOptions_NSStringEnumerationByParagraphs: NSStringEnumerationOptions = + 1; +pub const NSStringEnumerationOptions_NSStringEnumerationByComposedCharacterSequences: + NSStringEnumerationOptions = 2; +pub const NSStringEnumerationOptions_NSStringEnumerationByWords: NSStringEnumerationOptions = 3; +pub const NSStringEnumerationOptions_NSStringEnumerationBySentences: NSStringEnumerationOptions = 4; +pub const NSStringEnumerationOptions_NSStringEnumerationReverse: NSStringEnumerationOptions = 256; +pub const NSStringEnumerationOptions_NSStringEnumerationSubstringNotRequired: + NSStringEnumerationOptions = 512; +pub const NSStringEnumerationOptions_NSStringEnumerationLocalized: NSStringEnumerationOptions = + 1024; +pub type NSStringEnumerationOptions = NSUInteger; +pub type NSStringTransform = NSString; +extern "C" { + pub static mut NSStringTransformLatinToKatakana: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToHiragana: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToHangul: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToArabic: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToHebrew: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToThai: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToCyrillic: NonNull; +} +extern "C" { + pub static mut NSStringTransformLatinToGreek: NonNull; +} +extern "C" { + pub static mut NSStringTransformToLatin: NonNull; +} +extern "C" { + pub static mut NSStringTransformMandarinToLatin: NonNull; +} +extern "C" { + pub static mut NSStringTransformHiraganaToKatakana: NonNull; +} +extern "C" { + pub static mut NSStringTransformFullwidthToHalfwidth: NonNull; +} +extern "C" { + pub static mut NSStringTransformToXMLHex: NonNull; +} +extern "C" { + pub static mut NSStringTransformToUnicodeName: NonNull; +} +extern "C" { + pub static mut NSStringTransformStripCombiningMarks: NonNull; +} +extern "C" { + pub static mut NSStringTransformStripDiacritics: NonNull; +} +pub type NSStringEncodingDetectionOptionsKey = NSString; +#[doc = " NSStringEncodingDetection"] +impl NSString { + pub unsafe fn stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_( + data: NonNull, + opts: *mut NSDictionary, + string: NonNull, + usedLossyConversion: *mut c_schar, + ) -> NSStringEncoding { + msg_send![ + class!(NSString), + stringEncodingForData: data, + encodingOptions: opts, + convertedString: string, + usedLossyConversion: usedLossyConversion + ] + } +} +extern "C" { + pub static mut NSStringEncodingDetectionSuggestedEncodingsKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionDisallowedEncodingsKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionUseOnlySuggestedEncodingsKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionAllowLossyKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionFromWindowsKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionLossySubstitutionKey: NonNull; +} +extern "C" { + pub static mut NSStringEncodingDetectionLikelyLanguageKey: NonNull; +} +#[doc = " NSItemProvider"] +impl NSString {} +#[repr(transparent)] +pub struct NSMutableString(NSString); +impl core::ops::Deref for NSMutableString { + type Target = NSString; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSMutableString { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +unsafe impl Message for NSMutableString {} +unsafe impl RefEncode for NSMutableString { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSMutableString { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSString), alloc] + } +} +impl NSMutableString { + pub unsafe fn replaceCharactersInRange_withString_( + &self, + range: NSRange, + aString: NonNull, + ) { + msg_send![self, replaceCharactersInRange: range, withString: aString] + } +} +#[doc = " NSMutableStringExtensionMethods"] +impl NSMutableString { + pub unsafe fn insertString_atIndex_(&self, aString: NonNull, loc: NSUInteger) { + msg_send![self, insertString: aString, atIndex: loc] + } + pub unsafe fn deleteCharactersInRange_(&self, range: NSRange) { + msg_send![self, deleteCharactersInRange: range] + } + pub unsafe fn appendString_(&self, aString: NonNull) { + msg_send![self, appendString: aString] + } + pub unsafe fn appendFormat_(&self, format: NonNull) { + msg_send![self, appendFormat: format] + } + pub unsafe fn setString_(&self, aString: NonNull) { + msg_send![self, setString: aString] + } + pub unsafe fn replaceOccurrencesOfString_withString_options_range_( + &self, + target: *const NSString, + replacement: *const NSString, + options: NSStringCompareOptions, + searchRange: NSRange, + ) -> NSUInteger { + msg_send![ + self, + replaceOccurrencesOfString: target, + withString: replacement, + options: options, + range: searchRange + ] + } + pub unsafe fn applyTransform_reverse_range_updatedRange_( + &self, + transform: *const NSString, + reverse: Bool, + range: NSRange, + resultingRange: *mut NSRange, + ) -> Bool { + msg_send![ + self, + applyTransform: transform, + reverse: reverse, + range: range, + updatedRange: resultingRange + ] + } + pub unsafe fn initWithCapacity_( + this: Option, Unknown>>, + capacity: NSUInteger, + ) -> Id { + msg_send_id![this, initWithCapacity: capacity].unwrap_unchecked() + } + pub unsafe fn stringWithCapacity_(capacity: NSUInteger) -> Id { + msg_send_id![class!(NSMutableString), stringWithCapacity: capacity].unwrap_unchecked() + } +} +extern "C" { + pub static mut NSCharacterConversionException: NonNull; +} +extern "C" { + pub static mut NSParseErrorException: NonNull; +} +#[doc = " NSExtendedStringPropertyListParsing"] +impl NSString { + pub unsafe fn propertyList(&self) -> Id { + msg_send_id![self, propertyList].unwrap_unchecked() + } + pub unsafe fn propertyListFromStringsFileFormat(&self) -> Option> { + msg_send_id![self, propertyListFromStringsFileFormat] + } +} +#[doc = " NSStringDeprecated"] +impl NSString { + pub unsafe fn cString(&self) -> *const c_char { + msg_send![self, cString] + } + pub unsafe fn lossyCString(&self) -> *const c_char { + msg_send![self, lossyCString] + } + pub unsafe fn cStringLength(&self) -> NSUInteger { + msg_send![self, cStringLength] + } + pub unsafe fn getCString_(&self, bytes: *mut c_char) { + msg_send![self, getCString: bytes] + } + pub unsafe fn getCString_maxLength_(&self, bytes: *mut c_char, maxLength: NSUInteger) { + msg_send![self, getCString: bytes, maxLength: maxLength] + } + pub unsafe fn getCString_maxLength_range_remainingRange_( + &self, + bytes: *mut c_char, + maxLength: NSUInteger, + aRange: NSRange, + leftoverRange: *mut NSRange, + ) { + msg_send![ + self, + getCString: bytes, + maxLength: maxLength, + range: aRange, + remainingRange: leftoverRange + ] + } + pub unsafe fn writeToFile_atomically_( + &self, + path: NonNull, + useAuxiliaryFile: Bool, + ) -> Bool { + msg_send![self, writeToFile: path, atomically: useAuxiliaryFile] + } + pub unsafe fn writeToURL_atomically_(&self, url: NonNull, atomically: Bool) -> Bool { + msg_send![self, writeToURL: url, atomically: atomically] + } + pub unsafe fn initWithContentsOfFile_( + this: Option, Unknown>>, + path: NonNull, + ) -> Option> { + msg_send_id![this, initWithContentsOfFile: path] + } + pub unsafe fn initWithContentsOfURL_( + this: Option, Unknown>>, + url: NonNull, + ) -> Option> { + msg_send_id![this, initWithContentsOfURL: url] + } + pub unsafe fn initWithCStringNoCopy_length_freeWhenDone_( + this: Option, Unknown>>, + bytes: *mut c_char, + length: NSUInteger, + freeBuffer: Bool, + ) -> Option> { + msg_send_id![ + this, + initWithCStringNoCopy: bytes, + length: length, + freeWhenDone: freeBuffer + ] + } + pub unsafe fn initWithCString_length_( + this: Option, Unknown>>, + bytes: *const c_char, + length: NSUInteger, + ) -> Option> { + msg_send_id![this, initWithCString: bytes, length: length] + } + pub unsafe fn initWithCString_( + this: Option, Unknown>>, + bytes: *const c_char, + ) -> Option> { + msg_send_id![this, initWithCString: bytes] + } + pub unsafe fn getCharacters_(&self, buffer: *mut c_ushort) { + msg_send![self, getCharacters: buffer] + } + pub unsafe fn stringWithContentsOfFile_( + path: NonNull, + ) -> Option> { + msg_send_id![class!(NSString), stringWithContentsOfFile: path] + } + pub unsafe fn stringWithContentsOfURL_(url: NonNull) -> Option> { + msg_send_id![class!(NSString), stringWithContentsOfURL: url] + } + pub unsafe fn stringWithCString_length_( + bytes: *const c_char, + length: NSUInteger, + ) -> Option> { + msg_send_id![class!(NSString), stringWithCString: bytes, length: length] + } + pub unsafe fn stringWithCString_(bytes: *const c_char) -> Option> { + msg_send_id![class!(NSString), stringWithCString: bytes] + } +} +pub const NSProprietaryStringEncoding: NSStringEncoding = 65536; +pub type _bindgen_ty_11 = NSStringEncoding; +#[repr(transparent)] +pub struct NSSimpleCString(NSString); +impl core::ops::Deref for NSSimpleCString { + type Target = NSString; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSSimpleCString { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +unsafe impl Message for NSSimpleCString {} +unsafe impl RefEncode for NSSimpleCString { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSSimpleCString { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSSimpleCString), alloc] + } +} +impl NSSimpleCString {} +#[repr(transparent)] +pub struct NSConstantString(NSSimpleCString); +impl core::ops::Deref for NSConstantString { + type Target = NSSimpleCString; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSConstantString { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl NSConstantString { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSConstantString), alloc] + } +} +unsafe impl Message for NSConstantString {} +unsafe impl RefEncode for NSConstantString { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSConstantString {} diff --git a/objc2-foundation-sys/src/generated_others_shim.rs b/objc2-foundation-sys/src/generated_others_shim.rs new file mode 100644 index 000000000..a7c183bc2 --- /dev/null +++ b/objc2-foundation-sys/src/generated_others_shim.rs @@ -0,0 +1,131 @@ +//! Other quick examples + +use core::ptr::NonNull; + +use std::os::raw::c_void; + +use objc2::ffi::{NSInteger, NSUInteger}; +use objc2::rc::{Allocated, Id, Unknown}; +use objc2::runtime::Object; +use objc2::{class, msg_send, msg_send_id, Encoding, Message, RefEncode}; + +use crate::{NSCoder, NSObject, NSRange}; + +pub const NSComparisonResult_NSOrderedAscending: NSComparisonResult = -1; +pub const NSComparisonResult_NSOrderedSame: NSComparisonResult = 0; +pub const NSComparisonResult_NSOrderedDescending: NSComparisonResult = 1; +pub type NSComparisonResult = NSInteger; + +#[repr(transparent)] +pub struct NSArray(NSObject); +impl core::ops::Deref for NSArray { + type Target = NSObject; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSArray { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +unsafe impl Message for NSArray {} +unsafe impl RefEncode for NSArray { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSArray { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSArray), alloc] + } +} +impl NSArray { + pub unsafe fn objectAtIndex_(&self, index: NSUInteger) -> NonNull { + msg_send![self, objectAtIndex: index] + } + pub unsafe fn init(this: Option, Unknown>>) -> Id { + msg_send_id![this, init].unwrap_unchecked() + } + pub unsafe fn initWithObjects_count_( + this: Option, Unknown>>, + objects: NonNull<*mut Object>, + cnt: NSUInteger, + ) -> Id { + msg_send_id![this, initWithObjects: objects, count: cnt].unwrap_unchecked() + } + pub unsafe fn initWithCoder_( + this: Option, Unknown>>, + coder: NonNull, + ) -> Option> { + msg_send_id![this, initWithCoder: coder] + } + pub unsafe fn count(&self) -> NSUInteger { + msg_send![self, count] + } + pub unsafe fn firstObject(&self) -> Option> { + msg_send![self, firstObject] + } + pub unsafe fn lastObject(&self) -> Option> { + msg_send![self, lastObject] + } + pub unsafe fn getObjects_range_(&self, objects: NonNull>, range: NSRange) { + msg_send![self, getObjects: objects, range: range] + } +} + +#[repr(transparent)] +pub struct NSData(NSObject); +impl core::ops::Deref for NSData { + type Target = NSObject; + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl core::ops::DerefMut for NSData { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +unsafe impl Message for NSData {} +unsafe impl RefEncode for NSData { + const ENCODING_REF: Encoding<'static> = Encoding::Object; +} +impl NSData { + pub unsafe fn alloc() -> Option, Unknown>> { + msg_send_id![class!(NSData), alloc] + } +} +impl NSData { + pub unsafe fn length(&self) -> NSUInteger { + msg_send![self, length] + } + pub unsafe fn bytes(&self) -> *const c_void { + msg_send![self, bytes] + } +} +impl NSData { + pub unsafe fn initWithBytes_length_( + this: Option, Unknown>>, + bytes: *const c_void, + length: NSUInteger, + ) -> Id { + msg_send_id![this, initWithBytes: bytes, length: length].unwrap_unchecked() + } + pub unsafe fn initWithBytesNoCopy_length_deallocator_( + this: Option, Unknown>>, + bytes: *mut c_void, + length: NSUInteger, + deallocator: *mut c_void, + ) -> Id { + msg_send_id![ + this, + initWithBytesNoCopy: bytes, + length: length, + deallocator: deallocator, + ] + .unwrap_unchecked() + } +} diff --git a/objc2-foundation-sys/src/lib.rs b/objc2-foundation-sys/src/lib.rs new file mode 100644 index 000000000..3e6083b5c --- /dev/null +++ b/objc2-foundation-sys/src/lib.rs @@ -0,0 +1,19 @@ +#![no_std] +#![allow(non_camel_case_types)] +#![allow(clippy::upper_case_acronyms)] +#![allow(non_upper_case_globals)] +#![allow(non_snake_case)] +#![doc(html_root_url = "https://docs.rs/objc2-foundation-sys/0.0.1")] + +extern crate std; + +mod generated; + +#[allow(improper_ctypes)] // TODO +mod generated_nsstring; + +mod generated_others_shim; + +pub use generated::*; +pub use generated_nsstring::*; +pub use generated_others_shim::*; diff --git a/objc2-foundation/Cargo.toml b/objc2-foundation/Cargo.toml index 62e1ef931..a9b1c043f 100644 --- a/objc2-foundation/Cargo.toml +++ b/objc2-foundation/Cargo.toml @@ -22,20 +22,21 @@ default = ["std", "apple", "block"] block = ["block2"] # Currently not possible to turn off, put here for forwards compatibility. -std = ["alloc", "objc2/std", "block2?/std"] -alloc = ["objc2/alloc", "block2?/alloc"] +std = ["alloc", "objc2/std", "block2?/std", "objc2-foundation-sys/std"] +alloc = ["objc2/alloc", "block2?/alloc", "objc2-foundation-sys/alloc"] # Runtime selection. See `objc-sys` and `block-sys` for details. -apple = ["objc2/apple", "block2?/apple"] -gnustep-1-7 = ["objc2/gnustep-1-7", "block2?/gnustep-1-7"] -gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8", "block2?/gnustep-1-8"] -gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9", "block2?/gnustep-1-9"] -gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0", "block2?/gnustep-2-0"] -gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1", "block2?/gnustep-2-1"] +apple = ["objc2/apple", "block2?/apple", "objc2-foundation-sys/apple"] +gnustep-1-7 = ["objc2/gnustep-1-7", "block2?/gnustep-1-7", "objc2-foundation-sys/gnustep-1-7"] +gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8", "block2?/gnustep-1-8", "objc2-foundation-sys/gnustep-1-8"] +gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9", "block2?/gnustep-1-9", "objc2-foundation-sys/gnustep-1-9"] +gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0", "block2?/gnustep-2-0", "objc2-foundation-sys/gnustep-2-0"] +gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1", "block2?/gnustep-2-1", "objc2-foundation-sys/gnustep-2-1"] [dependencies] block2 = { path = "../block2", version = "=0.2.0-alpha.4", default-features = false, optional = true } objc2 = { path = "../objc2", version = "=0.3.0-beta.0", default-features = false } +objc2-foundation-sys = { path = "../objc2-foundation-sys", default-features = false } [package.metadata.docs.rs] default-target = "x86_64-apple-darwin" diff --git a/objc2-foundation/src/array.rs b/objc2-foundation/src/array.rs index aba3741c2..e914cce52 100644 --- a/objc2-foundation/src/array.rs +++ b/objc2-foundation/src/array.rs @@ -3,6 +3,7 @@ use core::cmp::Ordering; use core::ffi::c_void; use core::marker::PhantomData; use core::ops::{Index, IndexMut, Range}; +use core::ptr::NonNull; use objc2::msg_send; use objc2::rc::{DefaultId, Id, Owned, Ownership, Shared, SliceId}; @@ -10,8 +11,8 @@ use objc2::runtime::{Class, Object}; use objc2::Message; use super::{ - NSComparisonResult, NSCopying, NSEnumerator, NSFastEnumeration, NSMutableCopying, NSObject, - NSRange, + ffi, NSComparisonResult, NSCopying, NSEnumerator, NSFastEnumeration, NSMutableCopying, + NSObject, NSRange, }; object! { @@ -55,6 +56,11 @@ unsafe fn from_refs(cls: &Class, refs: &[&T]) -> *mut Objec count: refs.len(), ] } + + // let ptr = unsafe { NonNull::new_unchecked(refs.as_ptr() as *mut _) }; + // let obj: *mut ffi::NSArray = unsafe { msg_send![cls, alloc] }; + // let obj = unsafe { ffi::NSArray::initWithObjects_count_(obj, ptr, refs.len()) }; + // unsafe { obj.cast() } } impl NSArray { @@ -64,9 +70,13 @@ impl NSArray { } impl NSArray { + fn r(&self) -> &ffi::NSArray { + unsafe { &*(self as *const Self as *const ffi::NSArray) } + } + #[doc(alias = "count")] pub fn len(&self) -> usize { - unsafe { msg_send![self, count] } + unsafe { self.r().count() } } pub fn is_empty(&self) -> bool { @@ -78,7 +88,7 @@ impl NSArray { // TODO: Replace this check with catching the thrown NSRangeException if index < self.len() { // SAFETY: The index is checked to be in bounds. - Some(unsafe { msg_send![self, objectAtIndex: index] }) + Some(unsafe { self.r().objectAtIndex_(index).cast().as_ref() }) } else { None } @@ -86,12 +96,12 @@ impl NSArray { #[doc(alias = "firstObject")] pub fn first(&self) -> Option<&T> { - unsafe { msg_send![self, firstObject] } + unsafe { self.r().firstObject().map(|ptr| ptr.cast().as_ref()) } } #[doc(alias = "lastObject")] pub fn last(&self) -> Option<&T> { - unsafe { msg_send![self, lastObject] } + unsafe { self.r().lastObject().map(|ptr| ptr.cast().as_ref()) } } #[doc(alias = "objectEnumerator")] @@ -113,7 +123,9 @@ impl NSArray { let range = NSRange::from(range); let mut vec = Vec::with_capacity(range.length); unsafe { - let _: () = msg_send![self, getObjects: vec.as_ptr(), range: range]; + let tmp = [range.location, range.length]; // TMP + let ptr = NonNull::new_unchecked(vec.as_mut_ptr()).cast(); + self.r().getObjects_range_(ptr, tmp); vec.set_len(range.length); } vec @@ -159,7 +171,7 @@ impl NSArray { // TODO: Replace this check with catching the thrown NSRangeException if index < self.len() { // SAFETY: The index is checked to be in bounds. - Some(unsafe { msg_send![self, objectAtIndex: index] }) + Some(unsafe { self.r().objectAtIndex_(index).cast().as_mut() }) } else { None } @@ -167,12 +179,12 @@ impl NSArray { #[doc(alias = "firstObject")] pub fn first_mut(&mut self) -> Option<&mut T> { - unsafe { msg_send![self, firstObject] } + unsafe { self.r().firstObject().map(|ptr| ptr.cast().as_mut()) } } #[doc(alias = "lastObject")] pub fn last_mut(&mut self) -> Option<&mut T> { - unsafe { msg_send![self, lastObject] } + unsafe { self.r().lastObject().map(|ptr| ptr.cast().as_mut()) } } } diff --git a/objc2-foundation/src/comparison_result.rs b/objc2-foundation/src/comparison_result.rs index f276fa732..107bcef59 100644 --- a/objc2-foundation/src/comparison_result.rs +++ b/objc2-foundation/src/comparison_result.rs @@ -2,6 +2,8 @@ use core::cmp::Ordering; use objc2::{Encode, Encoding, RefEncode}; +use crate::ffi; + /// Constants that indicate sort order. /// /// See [Apple's documentation](https://developer.apple.com/documentation/foundation/nscomparisonresult?language=objc). @@ -9,11 +11,11 @@ use objc2::{Encode, Encoding, RefEncode}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum NSComparisonResult { /// The left operand is smaller than the right operand. - Ascending = -1, + Ascending = ffi::NSComparisonResult_NSOrderedAscending, /// The two operands are equal. - Same = 0, + Same = ffi::NSComparisonResult_NSOrderedSame, /// The left operand is greater than the right operand. - Descending = 1, + Descending = ffi::NSComparisonResult_NSOrderedDescending, } impl Default for NSComparisonResult { diff --git a/objc2-foundation/src/data.rs b/objc2-foundation/src/data.rs index 846f80278..877a5c257 100644 --- a/objc2-foundation/src/data.rs +++ b/objc2-foundation/src/data.rs @@ -9,7 +9,7 @@ use objc2::rc::{DefaultId, Id, Owned, Shared}; use objc2::runtime::{Class, Object}; use objc2::{msg_send, msg_send_id}; -use super::{NSCopying, NSMutableCopying, NSObject, NSRange}; +use super::{ffi, NSCopying, NSMutableCopying, NSObject, NSRange}; object! { /// A static byte buffer in memory. @@ -42,9 +42,13 @@ unsafe impl Send for NSMutableData {} impl NSData { unsafe_def_fn!(fn new -> Shared); + fn r(&self) -> &ffi::NSData { + unsafe { &*(self as *const Self as *const ffi::NSData) } + } + #[doc(alias = "length")] pub fn len(&self) -> usize { - unsafe { msg_send![self, length] } + unsafe { self.r().length() } } pub fn is_empty(&self) -> bool { @@ -52,7 +56,7 @@ impl NSData { } pub fn bytes(&self) -> &[u8] { - let ptr: *const c_void = unsafe { msg_send![self, bytes] }; + let ptr: *const c_void = unsafe { self.r().bytes() }; let ptr: *const u8 = ptr.cast(); // The bytes pointer may be null for length zero if ptr.is_null() { diff --git a/objc2-foundation/src/lib.rs b/objc2-foundation/src/lib.rs index 317f4b8dc..a28e09194 100644 --- a/objc2-foundation/src/lib.rs +++ b/objc2-foundation/src/lib.rs @@ -70,6 +70,8 @@ pub use self::value::NSValue; #[doc(no_inline)] pub use objc2::ffi::{NSInteger, NSUInteger}; +pub use objc2_foundation_sys as ffi; + #[cfg(feature = "apple")] #[link(name = "Foundation", kind = "framework")] extern "C" {} diff --git a/objc2-foundation/src/object.rs b/objc2-foundation/src/object.rs index d2b45e437..dfd4c0f98 100644 --- a/objc2-foundation/src/object.rs +++ b/objc2-foundation/src/object.rs @@ -1,7 +1,7 @@ use objc2::rc::{DefaultId, Id, Owned, Shared}; use objc2::runtime::{Class, Object}; -use objc2::{msg_send, msg_send_bool, msg_send_id}; +use super::ffi; use super::NSString; object! { @@ -10,23 +10,29 @@ object! { } impl NSObject { - unsafe_def_fn!(pub fn new -> Owned); + pub fn new() -> Id { + unsafe { Id::cast(ffi::NSObject::new().unwrap()).into_owned() } + } + + fn r(&self) -> &ffi::NSObject { + unsafe { &*(self as *const Self as *const ffi::NSObject) } + } pub fn hash_code(&self) -> usize { - unsafe { msg_send![self, hash] } + unsafe { self.r().hash() } } pub fn is_equal(&self, other: &NSObject) -> bool { - unsafe { msg_send_bool![self, isEqual: other] } + unsafe { self.r().isEqual_(other.r()).as_bool() } } pub fn description(&self) -> Id { // TODO: Verify that description always returns a non-null string - unsafe { msg_send_id![self, description].unwrap() } + unsafe { Id::cast(self.r().description().unwrap()).into_shared() } } pub fn is_kind_of(&self, cls: &Class) -> bool { - unsafe { msg_send_bool![self, isKindOfClass: cls] } + unsafe { self.r().isKindOfClass_(cls).as_bool() } } } diff --git a/objc2-foundation/src/string.rs b/objc2-foundation/src/string.rs index 64f3cab24..64fbc664f 100644 --- a/objc2-foundation/src/string.rs +++ b/objc2-foundation/src/string.rs @@ -7,14 +7,13 @@ use core::slice; use core::str; use std::os::raw::c_char; -use objc2::ffi; use objc2::rc::DefaultId; use objc2::rc::{autoreleasepool, AutoreleasePool}; use objc2::rc::{Id, Shared}; use objc2::runtime::{Class, Object}; use objc2::{msg_send, msg_send_bool}; -use crate::{NSComparisonResult, NSCopying, NSMutableCopying, NSMutableString, NSObject}; +use crate::{ffi, NSComparisonResult, NSCopying, NSMutableCopying, NSMutableString, NSObject}; #[cfg(feature = "apple")] const UTF8_ENCODING: usize = 4; @@ -23,7 +22,7 @@ const UTF8_ENCODING: i32 = 4; #[allow(unused)] #[allow(non_upper_case_globals)] -const NSNotFound: ffi::NSInteger = ffi::NSIntegerMax; +const NSNotFound: objc2::ffi::NSInteger = objc2::ffi::NSIntegerMax; object! { /// A static, plain-text Unicode string object. @@ -48,11 +47,18 @@ impl NSString { pub fn new -> Shared; } + fn r(&self) -> &ffi::NSString { + unsafe { &*(self as *const Self as *const ffi::NSString) } + } + /// The number of UTF-8 code units in `self`. #[doc(alias = "lengthOfBytesUsingEncoding")] #[doc(alias = "lengthOfBytesUsingEncoding:")] pub fn len(&self) -> usize { - unsafe { msg_send![self, lengthOfBytesUsingEncoding: UTF8_ENCODING] } + unsafe { + self.r() + .lengthOfBytesUsingEncoding_(ffi::NSUTF8StringEncoding) + } } /// The number of UTF-16 code units in `self`. @@ -139,7 +145,7 @@ impl NSString { // NSString OR the lifetime of the innermost @autoreleasepool. // // https://developer.apple.com/documentation/foundation/nsstring/1411189-utf8string?language=objc - let bytes: *const c_char = unsafe { msg_send![self, UTF8String] }; + let bytes: *const c_char = unsafe { self.r().UTF8String() }; let bytes: *const u8 = bytes.cast(); let len = self.len(); @@ -164,9 +170,18 @@ impl NSString { #[doc(alias = "initWithBytes:length:encoding:")] #[allow(clippy::should_implement_trait)] // Not really sure of a better name pub fn from_str(string: &str) -> Id { + let bytes = string.as_ptr() as *const c_void; unsafe { - let obj = from_str(Self::class(), string); - Id::new(obj.cast()).unwrap() + Id::cast( + ffi::NSString::initWithBytes_length_encoding_( + ffi::NSString::alloc(), + bytes, + string.len(), + ffi::NSUTF8StringEncoding, + ) + .unwrap(), + ) + .into_shared() } } diff --git a/objc2/src/__macro_helpers.rs b/objc2/src/__macro_helpers.rs index 7ce2ec021..189da606c 100644 --- a/objc2/src/__macro_helpers.rs +++ b/objc2/src/__macro_helpers.rs @@ -1,4 +1,4 @@ -use crate::rc::{Allocated, Id, Ownership}; +use crate::rc::{Allocated, Id, MaybeOwnership}; use crate::runtime::{Class, Sel}; use crate::{Message, MessageArguments, MessageReceiver}; @@ -51,7 +51,7 @@ pub trait MsgSendId { } // `new` -impl MsgSendId<&'_ Class, Id> +impl MsgSendId<&'_ Class, Id> for RetainSemantics { #[inline] @@ -69,7 +69,7 @@ impl MsgSendId<&'_ Class, Id> } // `alloc` -impl MsgSendId<&'_ Class, Id, O>> +impl MsgSendId<&'_ Class, Id, O>> for RetainSemantics { #[inline] @@ -87,7 +87,7 @@ impl MsgSendId<&'_ Class, Id, O> } // `init` -impl MsgSendId, O>>, Id> +impl MsgSendId, O>>, Id> for RetainSemantics { #[inline] @@ -111,7 +111,7 @@ impl MsgSendId, O>>, I } // `copy` and `mutableCopy` -impl MsgSendId> +impl MsgSendId> for RetainSemantics { #[inline] @@ -126,7 +126,7 @@ impl MsgSendId MsgSendId> +impl MsgSendId> for RetainSemantics { #[inline] diff --git a/objc2/src/message/mod.rs b/objc2/src/message/mod.rs index b29d27736..19b2c20b4 100644 --- a/objc2/src/message/mod.rs +++ b/objc2/src/message/mod.rs @@ -2,7 +2,7 @@ use core::mem; use core::mem::ManuallyDrop; use core::ptr::NonNull; -use crate::rc::{Id, Owned, Ownership}; +use crate::rc::{Id, MaybeOwnership, Owned}; use crate::runtime::{Class, Imp, Object, Sel}; use crate::{Encode, EncodeArguments, RefEncode}; @@ -115,10 +115,10 @@ pub(crate) mod private { impl<'a, T: Message + ?Sized> Sealed for &'a T {} impl<'a, T: Message + ?Sized> Sealed for &'a mut T {} - impl<'a, T: Message + ?Sized, O: Ownership> Sealed for &'a Id {} + impl<'a, T: Message + ?Sized, O: MaybeOwnership> Sealed for &'a Id {} impl<'a, T: Message + ?Sized> Sealed for &'a mut Id {} - impl Sealed for ManuallyDrop> {} + impl Sealed for ManuallyDrop> {} impl Sealed for *const Class {} impl<'a> Sealed for &'a Class {} @@ -266,7 +266,7 @@ unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut T { } } -unsafe impl<'a, T: Message + ?Sized, O: Ownership> MessageReceiver for &'a Id { +unsafe impl<'a, T: Message + ?Sized, O: MaybeOwnership> MessageReceiver for &'a Id { #[inline] fn __as_raw_receiver(self) -> *mut Object { (Id::as_ptr(self) as *mut T).cast() @@ -280,7 +280,7 @@ unsafe impl<'a, T: Message + ?Sized> MessageReceiver for &'a mut Id { } } -unsafe impl MessageReceiver for ManuallyDrop> { +unsafe impl MessageReceiver for ManuallyDrop> { #[inline] fn __as_raw_receiver(self) -> *mut Object { Id::consume_as_ptr(self).cast() diff --git a/objc2/src/rc/id.rs b/objc2/src/rc/id.rs index 2d67247a5..55044b3c3 100644 --- a/objc2/src/rc/id.rs +++ b/objc2/src/rc/id.rs @@ -7,7 +7,7 @@ use core::ptr::NonNull; use super::Allocated; use super::AutoreleasePool; -use super::{Owned, Ownership, Shared}; +use super::{MaybeOwnership, Owned, Ownership, Shared, Unknown}; use crate::ffi; use crate::Message; @@ -101,7 +101,7 @@ use crate::Message; // TODO: Figure out if `Message` bound on `T` would be better here? // TODO: Add `ptr::Thin` bound on `T` to allow for only extern types // TODO: Consider changing the name of Id -> Retain -pub struct Id { +pub struct Id { /// A pointer to the contained object. The pointer is always retained. /// /// It is important that this is `NonNull`, since we want to dereference @@ -125,7 +125,7 @@ pub struct Id { notunwindsafe: PhantomData<&'static mut ()>, } -impl Id { +impl Id { #[inline] unsafe fn new_nonnull(ptr: NonNull) -> Self { Self { @@ -137,7 +137,7 @@ impl Id { } } -impl Id, O> { +impl Id, O> { #[inline] pub(crate) unsafe fn new_allocated(ptr: *mut T) -> Option { // SAFETY: Upheld by the caller @@ -158,7 +158,7 @@ impl Id, O> { } } -impl Id { +impl Id { /// Constructs an [`Id`] to an object that already has +1 retain count. /// /// This is useful when you have a retain count that has been handed off @@ -258,7 +258,7 @@ impl Id { } // TODO: Add ?Sized bound -impl Id { +impl Id { /// Convert the type of the given object to another. /// /// This is equivalent to a `cast` between two pointers. @@ -546,6 +546,38 @@ impl Id { } } +impl Id { + /// TODO + #[inline] + pub unsafe fn into_owned(self) -> Id { + unsafe { self.into_ownership() } + } + + /// TODO + #[inline] + pub unsafe fn into_shared(self) -> Id { + unsafe { self.into_ownership() } + } + + /// TODO + #[inline] + pub unsafe fn into_ownership(self) -> Id { + let ptr = ManuallyDrop::new(self).ptr; + unsafe { Id::new_nonnull(ptr) } + } +} + +impl Id { + /// TODO + #[doc(alias = "objc_autorelease")] + #[must_use = "If you don't intend to use the object any more, just drop it as usual"] + #[inline] + pub fn autorelease(self, pool: &AutoreleasePool) -> *mut T { + pool.__verify_is_inner(); + self.autorelease_inner() + } +} + impl From> for Id { /// Downgrade from an owned to a shared [`Id`], allowing it to be cloned. #[inline] @@ -556,6 +588,15 @@ impl From> for Id { } } +impl From> for Id { + #[inline] + fn from(obj: Id) -> Self { + let ptr = ManuallyDrop::new(obj).ptr; + // SAFETY: The pointer is valid, and ownership is simply decreased + unsafe { >::new_nonnull(ptr) } + } +} + // TODO: Add ?Sized bound impl Clone for Id { /// Makes a clone of the shared object. @@ -580,7 +621,7 @@ impl Clone for Id { /// borrowed data. /// /// [dropck_eyepatch]: https://doc.rust-lang.org/nightly/nomicon/dropck.html#an-escape-hatch -impl Drop for Id { +impl Drop for Id { /// Releases the retained object. /// /// The contained object's destructor (if it has one) is never run! @@ -624,6 +665,9 @@ unsafe impl Send for Id {} /// access as having a `T` directly. unsafe impl Sync for Id {} +// TODO: Maybe implement Send and Sync for `O: Unknown`? + +// Explicitly using `Ownership` and not `MaybeOwnership` here! impl Deref for Id { type Target = T; @@ -647,7 +691,7 @@ impl DerefMut for Id { } } -impl fmt::Pointer for Id { +impl fmt::Pointer for Id { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.ptr.as_ptr(), f) } @@ -657,8 +701,11 @@ impl fmt::Pointer for Id { // // See https://doc.rust-lang.org/1.54.0/src/alloc/boxed.rs.html#1652-1675 // and the `Arc` implementation. +// +// TODO: MaybeOwnership? impl Unpin for Id {} +// TODO: MaybeOwnership? impl RefUnwindSafe for Id {} // Same as `Arc`. diff --git a/objc2/src/rc/mod.rs b/objc2/src/rc/mod.rs index ebbfdf19c..9f19e9d8d 100644 --- a/objc2/src/rc/mod.rs +++ b/objc2/src/rc/mod.rs @@ -70,7 +70,7 @@ pub use self::allocated::Allocated; pub use self::autorelease::{autoreleasepool, AutoreleasePool, AutoreleaseSafe}; pub use self::id::Id; pub use self::id_traits::{DefaultId, SliceId, SliceIdMut}; -pub use self::ownership::{Owned, Ownership, Shared}; +pub use self::ownership::{MaybeOwnership, Owned, Ownership, Shared, Unknown}; pub use self::weak_id::WeakId; #[cfg(test)] diff --git a/objc2/src/rc/ownership.rs b/objc2/src/rc/ownership.rs index 1ea2cddd2..8ef678c73 100644 --- a/objc2/src/rc/ownership.rs +++ b/objc2/src/rc/ownership.rs @@ -8,19 +8,31 @@ pub enum Owned {} #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Shared {} +/// TODO +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub enum Unknown {} + mod private { pub trait Sealed {} impl Sealed for super::Owned {} impl Sealed for super::Shared {} + impl Sealed for super::Unknown {} } +/// TODO +pub trait MaybeOwnership: private::Sealed + 'static {} + +impl MaybeOwnership for Owned {} +impl MaybeOwnership for Shared {} +impl MaybeOwnership for Unknown {} + /// A type that marks what type of ownership a struct has over the object(s) /// it contains; specifically, either [`Owned`] or [`Shared`]. /// /// This trait is sealed and not meant to be implemented outside of the this /// crate. -pub trait Ownership: private::Sealed + 'static {} +pub trait Ownership: private::Sealed + MaybeOwnership + 'static {} impl Ownership for Owned {} impl Ownership for Shared {}