1313use clone:: Clone ;
1414use cmp:: Eq ;
1515use fmt;
16- use iter:: Iterator ;
16+ use iter:: { Iterator , FromIterator } ;
1717use option:: { None , Option , Some } ;
1818use str:: OwnedStr ;
1919use to_str:: ToStr ;
20- use vec:: OwnedVector ;
21- use vec;
2220
2321/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
2422#[ deriving( Clone , DeepClone , Eq , Ord , TotalEq , TotalOrd , ToStr ) ]
@@ -221,10 +219,9 @@ impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
221219// Free functions
222220/////////////////////////////////////////////////////////////////////////////
223221
224- /// Takes each element in the iterator: if it is an error, no further
225- /// elements are taken, and the error is returned.
226- /// Should no error occur, a vector containing the values of each Result
227- /// is returned.
222+ /// Takes each element in the `Iterator`: if it is an `Err`, no further
223+ /// elements are taken, and the `Err` is returned. Should no `Err` occur, a
224+ /// vector containing the values of each `Result` is returned.
228225///
229226/// Here is an example which increments every integer in a vector,
230227/// checking for overflow:
@@ -237,17 +234,24 @@ impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
237234/// let res = collect(v.iter().map(|&x| inc_conditionally(x)));
238235/// assert!(res == Ok(~[2u, 3, 4]));
239236#[ inline]
240- pub fn collect < T , E , Iter : Iterator < Result < T , E > > > ( mut iterator : Iter )
241- -> Result < ~[ T ] , E > {
242- let ( lower, _) = iterator. size_hint ( ) ;
243- let mut vs: ~[ T ] = vec:: with_capacity ( lower) ;
244- for t in iterator {
245- match t {
246- Ok ( v) => vs. push ( v) ,
247- Err ( u) => return Err ( u)
237+ pub fn collect < T , E , Iter : Iterator < Result < T , E > > , V : FromIterator < T > > ( iter : Iter ) -> Result < V , E > {
238+ // FIXME(#11084): This should be twice as fast once this bug is closed.
239+ let mut iter = iter. scan ( None , |state, x| {
240+ match x {
241+ Ok ( x) => Some ( x) ,
242+ Err ( err) => {
243+ * state = Some ( err) ;
244+ None
245+ }
248246 }
247+ } ) ;
248+
249+ let v: V = FromIterator :: from_iterator ( & mut iter) ;
250+
251+ match iter. state {
252+ Some ( err) => Err ( err) ,
253+ None => Ok ( v) ,
249254 }
250- Ok ( vs)
251255}
252256
253257/// Perform a fold operation over the result values from an iterator.
@@ -291,8 +295,8 @@ mod tests {
291295 use super :: * ;
292296
293297 use iter:: range;
294- use vec:: ImmutableVector ;
295298 use to_str:: ToStr ;
299+ use vec:: ImmutableVector ;
296300
297301 pub fn op1 ( ) -> Result < int , ~str > { Ok ( 666 ) }
298302 pub fn op2 ( ) -> Result < int , ~str > { Err ( ~"sadface") }
@@ -347,21 +351,21 @@ mod tests {
347351
348352 #[test]
349353 fn test_collect() {
350- assert_eq!( collect(range(0, 0)
351- .map(|_| Ok::<int, ()>(0))),
352- Ok(~[]));
353- assert_eq!( collect(range(0, 3)
354- .map(|x| Ok::<int, ()>(x))),
355- Ok(~[0, 1, 2]));
356- assert_eq!( collect(range(0, 3)
357- .map(|x| if x > 1 { Err(x) } else { Ok(x) })),
358- Err(2));
354+ let v: Result<~[int], ()> = collect(range(0, 0).map(|_| Ok::<int, ()>(0)));
355+ assert_eq!(v, Ok(~[]));
356+
357+ let v: Result<~[int], ()> = collect(range(0, 3).map(|x| Ok::<int, ()>(x)));
358+ assert_eq!(v, Ok(~[0, 1, 2]));
359+
360+ let v: Result<~[int], int> = collect(range(0, 3)
361+ .map(|x| if x > 1 { Err(x) } else { Ok(x) }));
362+ assert_eq!(v, Err(2));
359363
360364 // test that it does not take more elements than it needs
361365 let functions = [|| Ok(()), || Err(1), || fail!()];
362366
363- assert_eq!( collect(functions.iter().map(|f| (*f)())),
364- Err(1));
367+ let v: Result<~[()], int> = collect(functions.iter().map(|f| (*f)()));
368+ assert_eq!(v, Err(1));
365369 }
366370
367371 #[test]
0 commit comments