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