Skip to content

Commit

Permalink
Properly use extern_methods! macro
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Aug 9, 2022
1 parent da73029 commit 65e38bb
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 76 deletions.
35 changes: 18 additions & 17 deletions objc2/src/foundation/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,34 +136,34 @@ extern_methods!(
/// Generic accessor methods.
unsafe impl<T: Message, O: Ownership> NSArray<T, O> {
#[doc(alias = "count")]
pub fn len(&self) -> usize {
unsafe { msg_send![self, count] }
}
#[sel(count)]
pub fn len(&self) -> usize;

pub fn is_empty(&self) -> bool {
self.len() == 0
}

#[sel(objectAtIndex:)]
unsafe fn get_unchecked(&self, index: usize) -> &T;

#[doc(alias = "objectAtIndex:")]
pub fn get(&self, index: usize) -> Option<&T> {
// 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.get_unchecked(index) })
} else {
None
}
}

#[doc(alias = "firstObject")]
pub fn first(&self) -> Option<&T> {
unsafe { msg_send![self, firstObject] }
}
#[sel(firstObject)]
pub fn first(&self) -> Option<&T>;

#[doc(alias = "lastObject")]
pub fn last(&self) -> Option<&T> {
unsafe { msg_send![self, lastObject] }
}
#[sel(lastObject)]
pub fn last(&self) -> Option<&T>;

#[doc(alias = "objectEnumerator")]
pub fn iter(&self) -> NSEnumerator<'_, T> {
Expand All @@ -173,11 +173,14 @@ extern_methods!(
}
}

#[sel(getObjects:range:)]
unsafe fn get_objects(&self, ptr: *mut &T, range: NSRange);

pub fn objects_in_range(&self, range: Range<usize>) -> Vec<&T> {
let range = NSRange::from(range);
let mut vec = Vec::with_capacity(range.length);
unsafe {
let _: () = msg_send![self, getObjects: vec.as_ptr(), range: range];
self.get_objects(vec.as_mut_ptr(), range);
vec.set_len(range.length);
}
vec
Expand Down Expand Up @@ -228,14 +231,12 @@ extern_methods!(
}

#[doc(alias = "firstObject")]
pub fn first_mut(&mut self) -> Option<&mut T> {
unsafe { msg_send![self, firstObject] }
}
#[sel(firstObject)]
pub fn first_mut(&mut self) -> Option<&mut T>;

#[doc(alias = "lastObject")]
pub fn last_mut(&mut self) -> Option<&mut T> {
unsafe { msg_send![self, lastObject] }
}
#[sel(lastObject)]
pub fn last_mut(&mut self) -> Option<&mut T>;
}
);

Expand Down
46 changes: 26 additions & 20 deletions objc2/src/foundation/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,12 @@ impl UnwindSafe for NSData {}
impl RefUnwindSafe for NSData {}

extern_methods!(
/// Creation methods.
unsafe impl NSData {
pub fn new() -> Id<Self, Shared> {
unsafe { msg_send_id![Self::class(), new].unwrap() }
}

#[doc(alias = "length")]
pub fn len(&self) -> usize {
unsafe { msg_send![self, length] }
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn bytes(&self) -> &[u8] {
let ptr: *const c_void = unsafe { msg_send![self, bytes] };
let ptr: *const u8 = ptr.cast();
// The bytes pointer may be null for length zero
if ptr.is_null() {
&[]
} else {
unsafe { slice::from_raw_parts(ptr, self.len()) }
}
}

pub fn with_bytes(bytes: &[u8]) -> Id<Self, Shared> {
unsafe { Id::cast(with_slice(Self::class(), bytes)) }
}
Expand All @@ -80,6 +61,31 @@ extern_methods!(
unsafe { Id::cast(with_vec(cls, bytes)) }
}
}

/// Accessor methods.
unsafe impl NSData {
#[sel(length)]
#[doc(alias = "length")]
pub fn len(&self) -> usize;

#[sel(bytes)]
fn bytes_raw(&self) -> *const c_void;

pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn bytes(&self) -> &[u8] {
let ptr = self.bytes_raw();
let ptr: *const u8 = ptr.cast();
// The bytes pointer may be null for length zero
if ptr.is_null() {
&[]
} else {
unsafe { slice::from_raw_parts(ptr, self.len()) }
}
}
}
);

unsafe impl NSCopying for NSData {
Expand Down
17 changes: 8 additions & 9 deletions objc2/src/foundation/mutable_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,22 @@ extern_methods!(
old_obj
}

#[sel(removeObjectAtIndex:)]
unsafe fn remove_at(&mut self, index: usize);

#[doc(alias = "removeObjectAtIndex:")]
pub fn remove(&mut self, index: usize) -> Id<T, O> {
let obj = if let Some(obj) = self.get(index) {
unsafe { Id::retain_autoreleased(obj as *const T as *mut T).unwrap_unchecked() }
} else {
panic!("removal index should be < len");
};
unsafe {
let _: () = msg_send![self, removeObjectAtIndex: index];
}
unsafe { self.remove_at(index) };
obj
}

fn remove_last(&mut self) {
unsafe { msg_send![self, removeLastObject] }
}
#[sel(removeLastObject)]
fn remove_last(&mut self);

#[doc(alias = "removeLastObject")]
pub fn pop(&mut self) -> Option<Id<T, O>> {
Expand All @@ -132,9 +132,8 @@ extern_methods!(
}

#[doc(alias = "removeAllObjects")]
pub fn clear(&mut self) {
unsafe { msg_send![self, removeAllObjects] }
}
#[sel(removeAllObjects)]
pub fn clear(&mut self);

#[doc(alias = "sortUsingFunction:context:")]
pub fn sort_by<F: FnMut(&T, &T) -> Ordering>(&mut self, compare: F) {
Expand Down
34 changes: 15 additions & 19 deletions objc2/src/foundation/mutable_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,17 @@ extern_methods!(

/// Mutation methods
unsafe impl NSMutableData {
// Helps with reborrowing issue
fn raw_bytes_mut(&mut self) -> *mut c_void {
unsafe { msg_send![self, mutableBytes] }
}
/// Expands with zeroes, or truncates the buffer.
#[doc(alias = "setLength:")]
#[sel(setLength:)]
pub fn set_len(&mut self, len: usize);

#[sel(mutableBytes)]
fn bytes_mut_raw(&mut self) -> *mut c_void;

#[doc(alias = "mutableBytes")]
pub fn bytes_mut(&mut self) -> &mut [u8] {
let ptr = self.raw_bytes_mut();
let ptr = self.bytes_mut_raw();
let ptr: *mut u8 = ptr.cast();
// The bytes pointer may be null for length zero
if ptr.is_null() {
Expand All @@ -83,36 +86,29 @@ extern_methods!(
}
}

/// Expands with zeroes, or truncates the buffer.
#[doc(alias = "setLength:")]
pub fn set_len(&mut self, len: usize) {
unsafe { msg_send![self, setLength: len] }
}
#[sel(appendBytes:length:)]
unsafe fn append_raw(&mut self, ptr: *const c_void, len: usize);

#[doc(alias = "appendBytes:length:")]
pub fn extend_from_slice(&mut self, bytes: &[u8]) {
let bytes_ptr: *const c_void = bytes.as_ptr().cast();
unsafe { msg_send![self, appendBytes: bytes_ptr, length: bytes.len()] }
unsafe { self.append_raw(bytes_ptr, bytes.len()) }
}

pub fn push(&mut self, byte: u8) {
self.extend_from_slice(&[byte])
}

#[sel(replaceBytesInRange:withBytes:length:)]
unsafe fn replace_raw(&mut self, range: NSRange, ptr: *const c_void, len: usize);

#[doc(alias = "replaceBytesInRange:withBytes:length:")]
pub fn replace_range(&mut self, range: Range<usize>, bytes: &[u8]) {
let range = NSRange::from(range);
// No need to verify the length of the range here,
// `replaceBytesInRange:` just zero-fills if out of bounds.
let ptr: *const c_void = bytes.as_ptr().cast();
unsafe {
msg_send![
self,
replaceBytesInRange: range,
withBytes: ptr,
length: bytes.len(),
]
}
unsafe { self.replace_raw(range, ptr, bytes.len()) }
}

pub fn set_bytes(&mut self, bytes: &[u8]) {
Expand Down
14 changes: 6 additions & 8 deletions objc2/src/foundation/mutable_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,15 @@ extern_methods!(
unsafe impl NSMutableString {
/// Appends the given [`NSString`] onto the end of this.
#[doc(alias = "appendString:")]
pub fn push_nsstring(&mut self, nsstring: &NSString) {
// SAFETY: The string is not nil
unsafe { msg_send![self, appendString: nsstring] }
}
// SAFETY: The string is not nil
#[sel(appendString:)]
pub fn push_nsstring(&mut self, nsstring: &NSString);

/// Replaces the entire string.
#[doc(alias = "setString:")]
pub fn replace(&mut self, nsstring: &NSString) {
// SAFETY: The string is not nil
unsafe { msg_send![self, setString: nsstring] }
}
// SAFETY: The string is not nil
#[sel(setString:)]
pub fn replace(&mut self, nsstring: &NSString);

// TODO:
// - deleteCharactersInRange:
Expand Down
5 changes: 2 additions & 3 deletions objc2/src/foundation/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ extern_methods!(
/// See also [`NSString::len`].
#[doc(alias = "length")]
// TODO: Finish this
fn len_utf16(&self) -> usize {
unsafe { msg_send![self, length] }
}
#[sel(length)]
fn len_utf16(&self) -> usize;

pub fn is_empty(&self) -> bool {
// TODO: lengthOfBytesUsingEncoding: might sometimes return 0 for
Expand Down

0 comments on commit 65e38bb

Please sign in to comment.