Add a try_collect()
helper method to Iterator
· rust-lang/rust@47d5196 (original) (raw)
1
1
`use crate::cmp::{self, Ordering};
`
2
2
`use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try};
`
3
3
``
``
4
`+
use super::super::try_process;
`
4
5
`use super::super::TrustedRandomAccessNoCoerce;
`
5
6
`use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
`
6
7
`use super::super::{FlatMap, Flatten};
`
`@@ -1777,6 +1778,87 @@ pub trait Iterator {
`
1777
1778
`FromIterator::from_iter(self)
`
1778
1779
`}
`
1779
1780
``
``
1781
`+
/// Fallibly transforms an iterator into a collection, short circuiting if
`
``
1782
`+
/// a failure is encountered.
`
``
1783
`+
///
`
``
1784
`` +
/// try_collect()
is a variation of [collect()
][collect
] that allows fallible
``
``
1785
`+
/// conversions during collection. Its main use case is simplifying conversions from
`
``
1786
`` +
/// iterators yielding [Option<T>
][Option
] into Option<Collection<T>>
, or similarly for other [Try
]
``
``
1787
`` +
/// types (e.g. [Result
]).
``
``
1788
`+
///
`
``
1789
`` +
/// Importantly, try_collect()
doesn't require that the outer [Try
] type also implements [FromIterator
];
``
``
1790
`` +
/// only the inner type produced on Try::Output
must implement it. Concretely,
``
``
1791
`` +
/// this means that collecting into ControlFlow<_, Vec<i32>>
is valid because Vec<i32>
implements
``
``
1792
`` +
/// [FromIterator
], even though [ControlFlow
] doesn't.
``
``
1793
`+
///
`
``
1794
`` +
/// Also, if a failure is encountered during try_collect()
, the iterator is still valid and
``
``
1795
`+
/// may continue to be used, in which case it will continue iterating starting after the element that
`
``
1796
`+
/// triggered the failure. See the last example below for an example of how this works.
`
``
1797
`+
///
`
``
1798
`+
/// # Examples
`
``
1799
`` +
/// Successfully collecting an iterator of Option<i32>
into Option<Vec<i32>>
:
``
``
1800
/// ```
``
1801
`+
/// #![feature(iterator_try_collect)]
`
``
1802
`+
///
`
``
1803
`+
/// let u = vec![Some(1), Some(2), Some(3)];
`
``
1804
`+
/// let v = u.into_iter().try_collect::<Vec>();
`
``
1805
`+
/// assert_eq!(v, Some(vec![1, 2, 3]));
`
``
1806
/// ```
``
1807
`+
///
`
``
1808
`+
/// Failing to collect in the same way:
`
``
1809
/// ```
``
1810
`+
/// #![feature(iterator_try_collect)]
`
``
1811
`+
///
`
``
1812
`+
/// let u = vec![Some(1), Some(2), None, Some(3)];
`
``
1813
`+
/// let v = u.into_iter().try_collect::<Vec>();
`
``
1814
`+
/// assert_eq!(v, None);
`
``
1815
/// ```
``
1816
`+
///
`
``
1817
`` +
/// A similar example, but with Result
:
``
``
1818
/// ```
``
1819
`+
/// #![feature(iterator_try_collect)]
`
``
1820
`+
///
`
``
1821
`+
/// let u: Vec<Result<i32, ()>> = vec![Ok(1), Ok(2), Ok(3)];
`
``
1822
`+
/// let v = u.into_iter().try_collect::<Vec>();
`
``
1823
`+
/// assert_eq!(v, Ok(vec![1, 2, 3]));
`
``
1824
`+
///
`
``
1825
`+
/// let u = vec![Ok(1), Ok(2), Err(()), Ok(3)];
`
``
1826
`+
/// let v = u.into_iter().try_collect::<Vec>();
`
``
1827
`+
/// assert_eq!(v, Err(()));
`
``
1828
/// ```
``
1829
`+
///
`
``
1830
`` +
/// Finally, even [ControlFlow
] works, despite the fact that it
``
``
1831
`` +
/// doesn't implement [FromIterator
]. Note also that the iterator can
``
``
1832
`+
/// continue to be used, even if a failure is encountered:
`
``
1833
`+
///
`
``
1834
/// ```
``
1835
`+
/// #![feature(iterator_try_collect)]
`
``
1836
`+
///
`
``
1837
`+
/// use core::ops::ControlFlow::{Break, Continue};
`
``
1838
`+
///
`
``
1839
`+
/// let u = [Continue(1), Continue(2), Break(3), Continue(4), Continue(5)];
`
``
1840
`+
/// let mut it = u.into_iter();
`
``
1841
`+
///
`
``
1842
`+
/// let v = it.try_collect::<Vec<_>>();
`
``
1843
`+
/// assert_eq!(v, Break(3));
`
``
1844
`+
///
`
``
1845
`+
/// let v = it.try_collect::<Vec<_>>();
`
``
1846
`+
/// assert_eq!(v, Continue(vec![4, 5]));
`
``
1847
/// ```
``
1848
`+
///
`
``
1849
`` +
/// [collect
]: Iterator::collect
``
``
1850
`+
#[inline]
`
``
1851
`+
#[unstable(feature = "iterator_try_collect", issue = "94047")]
`
``
1852
`+
fn try_collect(&mut self) -> ChangeOutputType<Self::Item, B>
`
``
1853
`+
where
`
``
1854
`+
Self: Sized,
`
``
1855
`+
::Item: Try,
`
``
1856
`+
<::Item as Try>::Residual: Residual,
`
``
1857
`+
B: FromIterator<<Self::Item as Try>::Output>,
`
``
1858
`+
{
`
``
1859
`+
try_process(self, |i| i.collect())
`
``
1860
`+
}
`
``
1861
+
1780
1862
`/// Consumes an iterator, creating two collections from it.
`
1781
1863
`///
`
1782
1864
`` /// The predicate passed to partition()
can return true
, or false
.
``