13
13
use clone:: Clone ;
14
14
use cmp:: Eq ;
15
15
use fmt;
16
- use iter:: Iterator ;
16
+ use iter:: { Iterator , FromIterator } ;
17
17
use option:: { None , Option , Some } ;
18
18
use str:: OwnedStr ;
19
19
use to_str:: ToStr ;
20
- use vec:: OwnedVector ;
21
- use vec;
22
20
23
21
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
24
22
#[ 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> {
221
219
// Free functions
222
220
/////////////////////////////////////////////////////////////////////////////
223
221
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.
228
225
///
229
226
/// Here is an example which increments every integer in a vector,
230
227
/// checking for overflow:
@@ -237,17 +234,24 @@ impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
237
234
/// let res = collect(v.iter().map(|&x| inc_conditionally(x)));
238
235
/// assert!(res == Ok(~[2u, 3, 4]));
239
236
#[ 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
+ }
248
246
}
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) ,
249
254
}
250
- Ok ( vs)
251
255
}
252
256
253
257
/// Perform a fold operation over the result values from an iterator.
@@ -291,8 +295,8 @@ mod tests {
291
295
use super :: * ;
292
296
293
297
use iter:: range;
294
- use vec:: ImmutableVector ;
295
298
use to_str:: ToStr ;
299
+ use vec:: ImmutableVector ;
296
300
297
301
pub fn op1 ( ) -> Result < int , ~str > { Ok ( 666 ) }
298
302
pub fn op2 ( ) -> Result < int , ~str > { Err ( ~"sadface") }
@@ -347,21 +351,21 @@ mod tests {
347
351
348
352
#[test]
349
353
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));
359
363
360
364
// test that it does not take more elements than it needs
361
365
let functions = [|| Ok(()), || Err(1), || fail!()];
362
366
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));
365
369
}
366
370
367
371
#[test]
0 commit comments