diff --git a/objc2-foundation/examples/basic_usage.rs b/objc2-foundation/examples/basic_usage.rs index 5d6617892..6ac091250 100644 --- a/objc2-foundation/examples/basic_usage.rs +++ b/objc2-foundation/examples/basic_usage.rs @@ -1,4 +1,4 @@ -use objc2::rc::autoreleasepool; +use objc2::rc::{autoreleasepool, Id}; use objc2_foundation::{ INSArray, INSCopying, INSDictionary, INSString, NSArray, NSDictionary, NSObject, NSString, }; @@ -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, _> = 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 diff --git a/objc2-foundation/src/array.rs b/objc2-foundation/src/array.rs index 98f68f0ea..2a7fe133a 100644 --- a/objc2-foundation/src/array.rs +++ b/objc2-foundation/src/array.rs @@ -211,6 +211,52 @@ impl Index for NSArray { } } +impl From, Owned>> for Vec> +where + T: INSObject, + O: Ownership, +{ + fn from(array: Id, Owned>) -> Self { + let vec: Vec<&T> = (&*array).into(); + vec.into_iter() + .map(|obj| unsafe { Id::retain(obj.into()) }) + .collect() + } +} + +impl From>> for Id, Owned> +where + T: INSObject, + O: Ownership, +{ + fn from(vec: Vec>) -> Self { + unsafe { from_refs(vec.as_slice_ref()) } + } +} + +impl<'a, T, O> From<&'a NSArray> for Vec<&'a T> +where + T: INSObject, + O: Ownership, +{ + fn from(array: &'a NSArray) -> Self { + array.objects_in_range(0..array.count()) + } +} + +impl From<&'_ NSArray> for Vec> +where + T: INSObject, +{ + fn from(array: &NSArray) -> 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) { @@ -358,6 +404,16 @@ impl Index for NSMutableArray { } } +impl From>> for Id, Owned> +where + T: INSObject, + O: Ownership, +{ + fn from(vec: Vec>) -> Self { + unsafe { from_refs(vec.as_slice_ref()) } + } +} + #[cfg(test)] mod tests { use alloc::vec; @@ -374,7 +430,7 @@ mod tests { for _ in 0..len { vec.push(NSObject::new()); } - NSArray::from_vec(vec) + vec.into() } fn retain_count(obj: &T) -> usize { @@ -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); } @@ -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, Owned> = strings.into(); autoreleasepool(|pool| { strings.sort_by(|s1, s2| s1.as_str(pool).len().cmp(&s2.as_str(pool).len())); diff --git a/objc2-foundation/src/enumerator.rs b/objc2-foundation/src/enumerator.rs index 0f937683a..01f467040 100644 --- a/objc2-foundation/src/enumerator.rs +++ b/objc2-foundation/src/enumerator.rs @@ -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, _> = vec.into(); let enumerator = array.iter(); assert!(enumerator.count() == 4); @@ -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, _> = vec.into(); let enumerator = array.enumerator(); assert!(enumerator.count() == 4);