Skip to content

Commit

Permalink
Implement From for Id<NSArray> as an example
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Nov 2, 2021
1 parent 62c08ec commit 050603b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 10 deletions.
6 changes: 3 additions & 3 deletions objc2-foundation/examples/basic_usage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use objc2::rc::autoreleasepool;
use objc2::rc::{autoreleasepool, Id};
use objc2_foundation::{
INSArray, INSCopying, INSDictionary, INSString, NSArray, NSDictionary, NSObject, NSString,
};
Expand All @@ -13,14 +13,14 @@ fn main() {

// Create an NSArray from a Vec
let objs = vec![obj, obj2];
let array = NSArray::from_vec(objs);
let array: Id<NSArray<_, _>, _> = objs.into();
for obj in array.iter() {
println!("{:?}", obj);
}
println!("{}", array.len());

// Turn the NSArray back into a Vec
let mut objs = NSArray::into_vec(array);
let mut objs = Vec::from(array);
let obj = objs.pop().unwrap();

// Create an NSString from a str slice
Expand Down
62 changes: 59 additions & 3 deletions objc2-foundation/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,52 @@ impl<T: INSObject, O: Ownership> Index<usize> for NSArray<T, O> {
}
}

impl<T, O> From<Id<NSArray<T, O>, Owned>> for Vec<Id<T, O>>
where
T: INSObject,
O: Ownership,
{
fn from(array: Id<NSArray<T, O>, Owned>) -> Self {
let vec: Vec<&T> = (&*array).into();
vec.into_iter()
.map(|obj| unsafe { Id::retain(obj.into()) })
.collect()
}
}

impl<T, O> From<Vec<Id<T, O>>> for Id<NSArray<T, O>, Owned>
where
T: INSObject,
O: Ownership,
{
fn from(vec: Vec<Id<T, O>>) -> Self {
unsafe { from_refs(vec.as_slice_ref()) }
}
}

impl<'a, T, O> From<&'a NSArray<T, O>> for Vec<&'a T>
where
T: INSObject,
O: Ownership,
{
fn from(array: &'a NSArray<T, O>) -> Self {
array.objects_in_range(0..array.count())
}
}

impl<T> From<&'_ NSArray<T, Shared>> for Vec<Id<T, Shared>>
where
T: INSObject,
{
fn from(array: &NSArray<T, Shared>) -> Self {
array
.objects_in_range(0..array.count())
.into_iter()
.map(|obj| unsafe { Id::retain(obj.into()) })
.collect()
}
}

pub unsafe trait INSMutableArray: INSArray {
#[doc(alias = "addObject:")]
fn push(&mut self, obj: Id<Self::Item, Self::ItemOwnership>) {
Expand Down Expand Up @@ -358,6 +404,16 @@ impl<T: INSObject, O: Ownership> Index<usize> for NSMutableArray<T, O> {
}
}

impl<T, O> From<Vec<Id<T, O>>> for Id<NSMutableArray<T, O>, Owned>
where
T: INSObject,
O: Ownership,
{
fn from(vec: Vec<Id<T, O>>) -> Self {
unsafe { from_refs(vec.as_slice_ref()) }
}
}

#[cfg(test)]
mod tests {
use alloc::vec;
Expand All @@ -374,7 +430,7 @@ mod tests {
for _ in 0..len {
vec.push(NSObject::new());
}
NSArray::from_vec(vec)
vec.into()
}

fn retain_count<T: INSObject>(obj: &T) -> usize {
Expand Down Expand Up @@ -455,7 +511,7 @@ mod tests {
fn test_into_vec() {
let array = sample_array(4);

let vec = INSArray::into_vec(array);
let vec = Vec::from(array);
assert_eq!(vec.len(), 4);
}

Expand Down Expand Up @@ -504,7 +560,7 @@ mod tests {
#[test]
fn test_sort() {
let strings = vec![NSString::from_str("hello"), NSString::from_str("hi")];
let mut strings = NSMutableArray::from_vec(strings);
let mut strings: Id<NSMutableArray<_, _>, Owned> = strings.into();

autoreleasepool(|pool| {
strings.sort_by(|s1, s2| s1.as_str(pool).len().cmp(&s2.as_str(pool).len()));
Expand Down
11 changes: 7 additions & 4 deletions objc2-foundation/src/enumerator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,16 @@ impl<'a, C: INSFastEnumeration> Iterator for NSFastEnumerator<'a, C> {

#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use objc2::rc::Id;

use super::INSFastEnumeration;
use crate::{INSArray, INSValue, NSArray, NSValue};

#[test]
fn test_enumerator() {
let vec = (0u32..4).map(NSValue::new).collect();
let array = NSArray::from_vec(vec);
let vec: Vec<_> = (0u32..4).map(NSValue::new).collect();
let array: Id<NSArray<_, _>, _> = vec.into();

let enumerator = array.iter();
assert!(enumerator.count() == 4);
Expand All @@ -186,8 +189,8 @@ mod tests {

#[test]
fn test_fast_enumerator() {
let vec = (0u32..4).map(NSValue::new).collect();
let array = NSArray::from_vec(vec);
let vec: Vec<_> = (0u32..4).map(NSValue::new).collect();
let array: Id<NSArray<_, _>, _> = vec.into();

let enumerator = array.enumerator();
assert!(enumerator.count() == 4);
Expand Down

0 comments on commit 050603b

Please sign in to comment.