Skip to content

Commit dd9d965

Browse files
committed
Improve iterator traits for foundation types
1 parent 14ff594 commit dd9d965

File tree

6 files changed

+92
-8
lines changed

6 files changed

+92
-8
lines changed

objc2-foundation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88

99
### Added
1010
* Implement `UnwindSafe` and `RefUnwindSafe` for all objects.
11+
* Implemented `IntoIterator` for references to `NSArray`, `NSMutableArray`,
12+
`NSData` and `NSMutableData`.
13+
* Implemented `Extend` for `NSMutableArray`.
14+
* Add extra `Extend<&u8>` impl for `NSMutableData`.
1115

1216
### Fixed
1317
* Made `Debug` impls for all objects print something useful.

objc2-foundation/src/array.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use alloc::vec::Vec;
22
use core::fmt;
33
use core::marker::PhantomData;
4-
use core::ops::{Index, Range};
4+
use core::ops::{Index, IndexMut, Range};
55
use core::panic::{RefUnwindSafe, UnwindSafe};
66

77
use objc2::rc::{DefaultId, Id, Owned, Ownership, Shared, SliceId};
@@ -10,8 +10,8 @@ use objc2::Message;
1010
use objc2::{msg_send, msg_send_id};
1111

1212
use crate::{
13-
NSCopying, NSEnumerator, NSFastEnumeration, NSMutableArray, NSMutableCopying, NSObject,
14-
NSRange, __inner_extern_class,
13+
NSCopying, NSEnumerator, NSFastEnumeration, NSFastEnumerator, NSMutableArray, NSMutableCopying,
14+
NSObject, NSRange, __inner_extern_class,
1515
};
1616

1717
__inner_extern_class! {
@@ -199,6 +199,15 @@ unsafe impl<T: Message, O: Ownership> NSFastEnumeration for NSArray<T, O> {
199199
type Item = T;
200200
}
201201

202+
impl<'a, T: Message, O: Ownership> IntoIterator for &'a NSArray<T, O> {
203+
type Item = &'a T;
204+
type IntoIter = NSFastEnumerator<'a, NSArray<T, O>>;
205+
206+
fn into_iter(self) -> Self::IntoIter {
207+
self.iter_fast()
208+
}
209+
}
210+
202211
impl<T: Message, O: Ownership> Index<usize> for NSArray<T, O> {
203212
type Output = T;
204213

@@ -207,6 +216,12 @@ impl<T: Message, O: Ownership> Index<usize> for NSArray<T, O> {
207216
}
208217
}
209218

219+
impl<T: Message> IndexMut<usize> for NSArray<T, Owned> {
220+
fn index_mut(&mut self, index: usize) -> &mut T {
221+
self.get_mut(index).unwrap()
222+
}
223+
}
224+
210225
impl<T: Message> DefaultId for NSArray<T, Shared> {
211226
type Ownership = Shared;
212227

objc2-foundation/src/data.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,15 @@ impl fmt::Debug for NSData {
129129
}
130130
}
131131

132+
impl<'a> IntoIterator for &'a NSData {
133+
type Item = &'a u8;
134+
type IntoIter = core::slice::Iter<'a, u8>;
135+
136+
fn into_iter(self) -> Self::IntoIter {
137+
self.bytes().iter()
138+
}
139+
}
140+
132141
pub(crate) unsafe fn data_with_bytes(cls: &Class, bytes: &[u8]) -> *mut Object {
133142
let bytes_ptr: *const c_void = bytes.as_ptr().cast();
134143
unsafe {

objc2-foundation/src/mutable_array.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use objc2::{msg_send, msg_send_id};
1111

1212
use crate::array::from_refs;
1313
use crate::{
14-
NSArray, NSComparisonResult, NSCopying, NSFastEnumeration, NSMutableCopying, NSObject,
15-
__inner_extern_class,
14+
NSArray, NSComparisonResult, NSCopying, NSFastEnumeration, NSFastEnumerator, NSMutableCopying,
15+
NSObject, __inner_extern_class,
1616
};
1717

1818
__inner_extern_class! {
@@ -175,6 +175,22 @@ unsafe impl<T: Message, O: Ownership> NSFastEnumeration for NSMutableArray<T, O>
175175
type Item = T;
176176
}
177177

178+
impl<'a, T: Message, O: Ownership> IntoIterator for &'a NSMutableArray<T, O> {
179+
type Item = &'a T;
180+
type IntoIter = NSFastEnumerator<'a, NSMutableArray<T, O>>;
181+
182+
fn into_iter(self) -> Self::IntoIter {
183+
self.iter_fast()
184+
}
185+
}
186+
187+
impl<T: Message, O: Ownership> Extend<Id<T, O>> for NSMutableArray<T, O> {
188+
fn extend<I: IntoIterator<Item = Id<T, O>>>(&mut self, iter: I) {
189+
let iterator = iter.into_iter();
190+
iterator.for_each(move |item| self.push(item));
191+
}
192+
}
193+
178194
impl<T: Message, O: Ownership> Index<usize> for NSMutableArray<T, O> {
179195
type Output = T;
180196

objc2-foundation/src/mutable_data.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,16 @@ impl Extend<u8> for NSMutableData {
178178
///
179179
/// [`extend_from_slice`]: Self::extend_from_slice
180180
fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T) {
181-
for item in iter {
182-
self.push(item);
183-
}
181+
let iterator = iter.into_iter();
182+
iterator.for_each(move |item| self.push(item));
183+
}
184+
}
185+
186+
// Vec also has this impl
187+
impl<'a> Extend<&'a u8> for NSMutableData {
188+
fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T) {
189+
let iterator = iter.into_iter();
190+
iterator.for_each(move |item| self.push(*item));
184191
}
185192
}
186193

@@ -216,6 +223,24 @@ impl fmt::Debug for NSMutableData {
216223
}
217224
}
218225

226+
impl<'a> IntoIterator for &'a NSMutableData {
227+
type Item = &'a u8;
228+
type IntoIter = core::slice::Iter<'a, u8>;
229+
230+
fn into_iter(self) -> Self::IntoIter {
231+
self.bytes().iter()
232+
}
233+
}
234+
235+
impl<'a> IntoIterator for &'a mut NSMutableData {
236+
type Item = &'a mut u8;
237+
type IntoIter = core::slice::IterMut<'a, u8>;
238+
239+
fn into_iter(self) -> Self::IntoIter {
240+
self.bytes_mut().iter_mut()
241+
}
242+
}
243+
219244
#[cfg(test)]
220245
mod tests {
221246
use objc2::runtime::Object;
@@ -287,6 +312,8 @@ mod tests {
287312
let mut data = NSMutableData::with_bytes(&[1, 2]);
288313
data.extend(3..=5);
289314
assert_eq!(data.bytes(), &[1, 2, 3, 4, 5]);
315+
data.extend(&*NSData::with_bytes(&[6, 7]));
316+
assert_eq!(data.bytes(), &[1, 2, 3, 4, 5, 6, 7]);
290317
}
291318

292319
#[test]

objc2/src/rc/id_forwarding_impls.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,19 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Id<I, Owned> {
160160

161161
impl<I: FusedIterator + ?Sized> FusedIterator for Id<I, Owned> {}
162162

163+
// TODO: Consider this impl
164+
// impl<'a, T, O: Ownership> IntoIterator for &'a Id<T, O>
165+
// where
166+
// &'a T: IntoIterator,
167+
// {
168+
// type Item = <&'a T as IntoIterator>::Item;
169+
// type IntoIter = <&'a T as IntoIterator>::IntoIter;
170+
//
171+
// fn into_iter(self) -> Self::IntoIter {
172+
// (**self).into_iter()
173+
// }
174+
// }
175+
163176
impl<T, O: Ownership> borrow::Borrow<T> for Id<T, O> {
164177
fn borrow(&self) -> &T {
165178
Deref::deref(self)

0 commit comments

Comments
 (0)