Skip to content

Commit f3c6608

Browse files
committed
Auto merge of #107462 - WaffleLapkin:from_iterator_for_tuple, r=dtolnay
Implement `FromIterator` for `(impl Default + Extend, impl Default + Extend)` Similarly to how #85835 implemented `Extend` for `(impl Extend, impl Extend)`: ```rust impl<A, B, AE, BE> FromIterator<(AE, BE)> for (A, B) where A: Default + Extend<AE>, B: Default + Extend<BE>, { ... } ```
2 parents 7ab5eb8 + 7b5af57 commit f3c6608

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

library/core/src/iter/traits/collect.rs

+33
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,39 @@ pub trait FromIterator<A>: Sized {
150150
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
151151
}
152152

153+
/// This implementation turns an iterator of tuples into a tuple of types which implement
154+
/// [`Default`] and [`Extend`].
155+
///
156+
/// This is similar to [`Iterator::unzip`], but is also composable with other [`FromIterator`]
157+
/// implementations:
158+
///
159+
/// ```rust
160+
/// # fn main() -> Result<(), core::num::ParseIntError> {
161+
/// let string = "1,2,123,4";
162+
///
163+
/// let (numbers, lengths): (Vec<_>, Vec<_>) = string
164+
/// .split(',')
165+
/// .map(|s| s.parse().map(|n: u32| (n, s.len())))
166+
/// .collect::<Result<_, _>>()?;
167+
///
168+
/// assert_eq!(numbers, [1, 2, 123, 4]);
169+
/// assert_eq!(lengths, [1, 1, 3, 1]);
170+
/// # Ok(()) }
171+
/// ```
172+
#[stable(feature = "from_iterator_for_tuple", since = "CURRENT_RUSTC_VERSION")]
173+
impl<A, B, AE, BE> FromIterator<(AE, BE)> for (A, B)
174+
where
175+
A: Default + Extend<AE>,
176+
B: Default + Extend<BE>,
177+
{
178+
fn from_iter<I: IntoIterator<Item = (AE, BE)>>(iter: I) -> Self {
179+
let mut res = <(A, B)>::default();
180+
res.extend(iter);
181+
182+
res
183+
}
184+
}
185+
153186
/// Conversion into an [`Iterator`].
154187
///
155188
/// By implementing `IntoIterator` for a type, you define how it will be

0 commit comments

Comments
 (0)