Skip to content

Commit 6ab9c21

Browse files
committed
Add FromIterator implementations for Id
1 parent aa2d5b9 commit 6ab9c21

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

crates/objc2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5454
`extern_protocol!` and `declare_class!`.
5555
* Added `rc::IdIntoIterator` helper trait and forwarding `IntoIterator`
5656
implementations for `rc::Id`.
57+
* Added `rc::IdFromIterator` helper trait for implementing `IntoIterator`
58+
for `rc::Id`.
5759

5860
### Changed
5961
* **BREAKING**: `objc2::rc::AutoreleasePool` is now a zero-sized `Copy` type

crates/objc2/src/rc/id.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ use crate::{ffi, ClassType, Message};
5656
/// live on the stack, but instead must reside on the heap).
5757
///
5858
/// Note that because of current limitations in the Rust trait system, some
59-
/// traits like [`Default`] and [`IntoIterator`] are not directly
60-
/// implementable on `NSString`; for that ues-case, we provide the
61-
/// [`DefaultId`] and [`IdIntoIterator`] traits, which make the aforementioned
62-
/// traits available on `Id`.
59+
/// traits like [`Default`], [`IntoIterator`], [`FromIterator`], [`From`] and
60+
/// [`Into`] are not directly implementable on `NSString`; for that use-case,
61+
/// we instead provide the [`DefaultId`], [`IdIntoIterator`] and
62+
/// [`IdFromIterator`] traits, which make some of the the aforementioned
63+
/// traits implementable on `Id`.
6364
///
64-
/// [`IdIntoIterator`]: crate::rc::IdIntoIterator
6565
/// [`DefaultId`]: crate::rc::DefaultId
66+
/// [`IdIntoIterator`]: crate::rc::IdIntoIterator
67+
/// [`IdFromIterator`]: crate::rc::IdFromIterator
6668
///
6769
///
6870
/// # Memory layout

crates/objc2/src/rc/id_traits.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl<T: ?Sized + DefaultId> Default for Id<T> {
2323
/// Helper trait to implement [`IntoIterator`] on [`Id`].
2424
///
2525
/// This should be implemented in exactly the same fashion as if you were
26-
/// implementing `IntoIterator` for your type normally.
26+
/// just implementing `IntoIterator` for your type normally.
2727
//
2828
// Note that [`Box<T>` gets to cheat with regards moves][box-move], so
2929
// `boxed.into_iter()` is possible, while `id.into_iter()` is not possible
@@ -108,6 +108,23 @@ where
108108
}
109109
}
110110

111+
/// Helper trait to implement [`FromIterator`] on [`Id`].
112+
///
113+
/// This should be implemented in exactly the same fashion as if you were
114+
/// just implementing `FromIterator` for your type normally.
115+
pub trait IdFromIterator<T>: Sized {
116+
/// Creates an `Id` from an iterator.
117+
fn id_from_iter<I>(iter: I) -> Id<Self>
118+
where
119+
I: IntoIterator<Item = T>;
120+
}
121+
122+
impl<T, U: IdFromIterator<T>> FromIterator<T> for Id<U> {
123+
#[inline]
124+
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
125+
U::id_from_iter(iter)
126+
}
127+
}
111128

112129
#[cfg(test)]
113130
mod tests {
@@ -179,12 +196,18 @@ mod tests {
179196
}
180197
}
181198

182-
impl<'a> IntoIterator for Id<Collection> {
199+
impl IdIntoIterator for Collection {
183200
type Item = Id<NSObject>;
184201
type IntoIter = IntoIter;
185202

186-
fn into_iter(self) -> Self::IntoIter {
187-
IntoIter(self)
203+
fn id_into_iter(this: Id<Self>) -> Self::IntoIter {
204+
IntoIter(this)
205+
}
206+
}
207+
208+
impl IdFromIterator<Id<NSObject>> for Collection {
209+
fn id_from_iter<I: IntoIterator<Item = Id<NSObject>>>(_iter: I) -> Id<Self> {
210+
Collection::default_id()
188211
}
189212
}
190213

@@ -207,4 +230,10 @@ mod tests {
207230

208231
for _ in obj {}
209232
}
233+
234+
235+
#[test]
236+
fn test_from_iter() {
237+
let _: Id<Collection> = [NSObject::new()].into_iter().collect();
238+
}
210239
}

crates/objc2/src/rc/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ pub use self::autorelease::{
6262
autoreleasepool, autoreleasepool_leaking, AutoreleasePool, AutoreleaseSafe,
6363
};
6464
pub use self::id::Id;
65-
pub use self::id_traits::{DefaultId, IdIntoIterator};
65+
pub use self::id_traits::{DefaultId, IdIntoIterator, IdFromIterator};
6666
pub use self::test_object::{__RcTestObject, __ThreadTestData};
6767
pub use self::weak_id::WeakId;

0 commit comments

Comments
 (0)