Skip to content

Commit 9a8233d

Browse files
committed
stabilize core::result
Per API meeting https://github.com/rust-lang/meeting-minutes/blob/master/Meeting-API-review-2014-08-13.md Most of the module is marked as stable or unstable; most of the unstable items are awaiting resolution of conventions issues. * `collect`: this functionality is being moved to a new `FromIterator` impl. * `fold_` is deprecated due to lack of use * Several methods found in `core::option` are added here, including `iter`, `as_slice`, and variants. Due to deprecations, this is a: [breaking-change]
1 parent 276b8b1 commit 9a8233d

File tree

1 file changed

+173
-41
lines changed

1 file changed

+173
-41
lines changed

src/libcore/result.rs

Lines changed: 173 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,22 @@
274274
//! the context. The caller of `fail!` should assume that execution
275275
//! will not resume after failure, that failure is catastrophic.
276276
277+
#![stable]
278+
277279
use clone::Clone;
278280
use cmp::PartialEq;
279281
use std::fmt::Show;
280-
use iter::{Iterator, FromIterator};
282+
use slice;
283+
use slice::Slice;
284+
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
281285
use option::{None, Option, Some};
282286

283287
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
284288
///
285289
/// See the [`std::result`](index.html) module documentation for details.
286290
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
287291
#[must_use]
292+
#[stable]
288293
pub enum Result<T, E> {
289294
/// Contains the success value
290295
Ok(T),
@@ -315,6 +320,7 @@ impl<T, E> Result<T, E> {
315320
/// # }
316321
/// ~~~
317322
#[inline]
323+
#[stable]
318324
pub fn is_ok(&self) -> bool {
319325
match *self {
320326
Ok(_) => true,
@@ -335,6 +341,7 @@ impl<T, E> Result<T, E> {
335341
/// assert!(bogus.is_err());
336342
/// ~~~
337343
#[inline]
344+
#[stable]
338345
pub fn is_err(&self) -> bool {
339346
!self.is_ok()
340347
}
@@ -362,6 +369,7 @@ impl<T, E> Result<T, E> {
362369
/// let bdays: File = bdays.ok().expect("unable to open birthday file");
363370
/// ~~~
364371
#[inline]
372+
#[stable]
365373
pub fn ok(self) -> Option<T> {
366374
match self {
367375
Ok(x) => Some(x),
@@ -374,6 +382,7 @@ impl<T, E> Result<T, E> {
374382
/// Converts `self` into an `Option<T>`, consuming `self`,
375383
/// and discarding the value, if any.
376384
#[inline]
385+
#[stable]
377386
pub fn err(self) -> Option<E> {
378387
match self {
379388
Ok(_) => None,
@@ -390,6 +399,7 @@ impl<T, E> Result<T, E> {
390399
/// Produces a new `Result`, containing a reference
391400
/// into the original, leaving the original in place.
392401
#[inline]
402+
#[stable]
393403
pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
394404
match *self {
395405
Ok(ref x) => Ok(x),
@@ -399,13 +409,28 @@ impl<T, E> Result<T, E> {
399409

400410
/// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
401411
#[inline]
412+
#[unstable = "waiting for mut conventions"]
402413
pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
403414
match *self {
404415
Ok(ref mut x) => Ok(x),
405416
Err(ref mut x) => Err(x),
406417
}
407418
}
408419

420+
/// Convert from `Result<T, E>` to `&mut [T]` (without copying)
421+
#[inline]
422+
#[unstable = "waiting for mut conventions"]
423+
pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
424+
match *self {
425+
Ok(ref mut x) => slice::mut_ref_slice(x),
426+
Err(_) => {
427+
// work around lack of implicit coercion from fixed-size array to slice
428+
let emp: &mut [_] = &mut [];
429+
emp
430+
}
431+
}
432+
}
433+
409434
/////////////////////////////////////////////////////////////////////////
410435
// Transforming contained values
411436
/////////////////////////////////////////////////////////////////////////
@@ -441,6 +466,7 @@ impl<T, E> Result<T, E> {
441466
/// assert!(sum == 10);
442467
/// ~~~
443468
#[inline]
469+
#[unstable = "waiting for unboxed closures"]
444470
pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
445471
match self {
446472
Ok(t) => Ok(op(t)),
@@ -454,19 +480,47 @@ impl<T, E> Result<T, E> {
454480
/// This function can be used to pass through a successful result while handling
455481
/// an error.
456482
#[inline]
483+
#[unstable = "waiting for unboxed closures"]
457484
pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
458485
match self {
459486
Ok(t) => Ok(t),
460487
Err(e) => Err(op(e))
461488
}
462489
}
463490

491+
492+
/////////////////////////////////////////////////////////////////////////
493+
// Iterator constructors
494+
/////////////////////////////////////////////////////////////////////////
495+
496+
/// Returns an iterator over the possibly contained value.
497+
#[inline]
498+
#[unstable = "waiting for iterator conventions"]
499+
pub fn iter<'r>(&'r self) -> Item<&'r T> {
500+
Item{opt: self.as_ref().ok()}
501+
}
502+
503+
/// Returns a mutable iterator over the possibly contained value.
504+
#[inline]
505+
#[unstable = "waiting for iterator conventions"]
506+
pub fn mut_iter<'r>(&'r mut self) -> Item<&'r mut T> {
507+
Item{opt: self.as_mut().ok()}
508+
}
509+
510+
/// Returns a consuming iterator over the possibly contained value.
511+
#[inline]
512+
#[unstable = "waiting for iterator conventions"]
513+
pub fn move_iter(self) -> Item<T> {
514+
Item{opt: self.ok()}
515+
}
516+
464517
////////////////////////////////////////////////////////////////////////
465518
// Boolean operations on the values, eager and lazy
466519
/////////////////////////////////////////////////////////////////////////
467520

468521
/// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
469522
#[inline]
523+
#[stable]
470524
pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
471525
match self {
472526
Ok(_) => res,
@@ -478,6 +532,7 @@ impl<T, E> Result<T, E> {
478532
///
479533
/// This function can be used for control flow based on result values
480534
#[inline]
535+
#[unstable = "waiting for unboxed closures"]
481536
pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
482537
match self {
483538
Ok(t) => op(t),
@@ -487,6 +542,7 @@ impl<T, E> Result<T, E> {
487542

488543
/// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
489544
#[inline]
545+
#[stable]
490546
pub fn or(self, res: Result<T, E>) -> Result<T, E> {
491547
match self {
492548
Ok(_) => self,
@@ -498,6 +554,7 @@ impl<T, E> Result<T, E> {
498554
///
499555
/// This function can be used for control flow based on result values
500556
#[inline]
557+
#[unstable = "waiting for unboxed closures"]
501558
pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
502559
match self {
503560
Ok(t) => Ok(t),
@@ -508,6 +565,7 @@ impl<T, E> Result<T, E> {
508565
/// Unwraps a result, yielding the content of an `Ok`.
509566
/// Else it returns `optb`.
510567
#[inline]
568+
#[unstable = "waiting for conventions"]
511569
pub fn unwrap_or(self, optb: T) -> T {
512570
match self {
513571
Ok(t) => t,
@@ -518,6 +576,7 @@ impl<T, E> Result<T, E> {
518576
/// Unwraps a result, yielding the content of an `Ok`.
519577
/// If the value is an `Err` then it calls `op` with its value.
520578
#[inline]
579+
#[unstable = "waiting for conventions"]
521580
pub fn unwrap_or_else(self, op: |E| -> T) -> T {
522581
match self {
523582
Ok(t) => t,
@@ -541,6 +600,7 @@ impl<T, E: Show> Result<T, E> {
541600
/// Fails if the value is an `Err`, with a custom failure message provided
542601
/// by the `Err`'s value.
543602
#[inline]
603+
#[unstable = "waiting for conventions"]
544604
pub fn unwrap(self) -> T {
545605
match self {
546606
Ok(t) => t,
@@ -558,6 +618,7 @@ impl<T: Show, E> Result<T, E> {
558618
/// Fails if the value is an `Ok`, with a custom failure message provided
559619
/// by the `Ok`'s value.
560620
#[inline]
621+
#[unstable = "waiting for conventions"]
561622
pub fn unwrap_err(self) -> E {
562623
match self {
563624
Ok(t) =>
@@ -568,57 +629,124 @@ impl<T: Show, E> Result<T, E> {
568629
}
569630

570631
/////////////////////////////////////////////////////////////////////////////
571-
// Free functions
632+
// Trait implementations
572633
/////////////////////////////////////////////////////////////////////////////
573634

574-
/// Takes each element in the `Iterator`: if it is an `Err`, no further
575-
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
576-
/// vector containing the values of each `Result` is returned.
577-
///
578-
/// Here is an example which increments every integer in a vector,
579-
/// checking for overflow:
580-
///
581-
/// ```rust
582-
/// use std::result;
583-
/// use std::uint;
635+
impl<T, E> Slice<T> for Result<T, E> {
636+
/// Convert from `Result<T, E>` to `&[T]` (without copying)
637+
#[inline]
638+
#[stable]
639+
fn as_slice<'a>(&'a self) -> &'a [T] {
640+
match *self {
641+
Ok(ref x) => slice::ref_slice(x),
642+
Err(_) => {
643+
// work around lack of implicit coercion from fixed-size array to slice
644+
let emp: &[_] = &[];
645+
emp
646+
}
647+
}
648+
}
649+
}
650+
651+
/////////////////////////////////////////////////////////////////////////////
652+
// The Result Iterator
653+
/////////////////////////////////////////////////////////////////////////////
654+
655+
/// A `Result` iterator that yields either one or zero elements
584656
///
585-
/// let v = vec!(1u, 2u);
586-
/// let res: Result<Vec<uint>, &'static str> = result::collect(v.iter().map(|x: &uint|
587-
/// if *x == uint::MAX { Err("Overflow!") }
588-
/// else { Ok(x + 1) }
589-
/// ));
590-
/// assert!(res == Ok(vec!(2u, 3u)));
591-
/// ```
592-
#[inline]
593-
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
594-
// FIXME(#11084): This could be replaced with Iterator::scan when this
595-
// performance bug is closed.
657+
/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter`
658+
/// methods on `Result`.
659+
#[deriving(Clone)]
660+
#[unstable = "waiting for iterator conventions"]
661+
pub struct Item<T> {
662+
opt: Option<T>
663+
}
664+
665+
impl<T> Iterator<T> for Item<T> {
666+
#[inline]
667+
fn next(&mut self) -> Option<T> {
668+
self.opt.take()
669+
}
670+
671+
#[inline]
672+
fn size_hint(&self) -> (uint, Option<uint>) {
673+
match self.opt {
674+
Some(_) => (1, Some(1)),
675+
None => (0, Some(0)),
676+
}
677+
}
678+
}
596679

597-
struct Adapter<Iter, E> {
598-
iter: Iter,
599-
err: Option<E>,
680+
impl<A> DoubleEndedIterator<A> for Item<A> {
681+
#[inline]
682+
fn next_back(&mut self) -> Option<A> {
683+
self.opt.take()
600684
}
685+
}
686+
687+
impl<A> ExactSize<A> for Item<A> {}
601688

602-
impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> {
603-
#[inline]
604-
fn next(&mut self) -> Option<T> {
605-
match self.iter.next() {
606-
Some(Ok(value)) => Some(value),
607-
Some(Err(err)) => {
608-
self.err = Some(err);
609-
None
689+
/////////////////////////////////////////////////////////////////////////////
690+
// Free functions
691+
/////////////////////////////////////////////////////////////////////////////
692+
693+
/// Deprecated: use `Iterator::collect`.
694+
#[inline]
695+
#[deprecated = "use Iterator::collect instead"]
696+
pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(mut iter: Iter)
697+
-> Result<V, E> {
698+
iter.collect()
699+
}
700+
701+
impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
702+
/// Takes each element in the `Iterator`: if it is an `Err`, no further
703+
/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
704+
/// container with the values of each `Result` is returned.
705+
///
706+
/// Here is an example which increments every integer in a vector,
707+
/// checking for overflow:
708+
///
709+
/// ```rust
710+
/// use std::uint;
711+
///
712+
/// let v = vec!(1u, 2u);
713+
/// let res: Result<Vec<uint>, &'static str> = v.iter().map(|x: &uint|
714+
/// if *x == uint::MAX { Err("Overflow!") }
715+
/// else { Ok(x + 1) }
716+
/// ).collect();
717+
/// assert!(res == Ok(vec!(2u, 3u)));
718+
/// ```
719+
#[inline]
720+
fn from_iter<I: Iterator<Result<A, E>>>(iter: I) -> Result<V, E> {
721+
// FIXME(#11084): This could be replaced with Iterator::scan when this
722+
// performance bug is closed.
723+
724+
struct Adapter<Iter, E> {
725+
iter: Iter,
726+
err: Option<E>,
727+
}
728+
729+
impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> {
730+
#[inline]
731+
fn next(&mut self) -> Option<T> {
732+
match self.iter.next() {
733+
Some(Ok(value)) => Some(value),
734+
Some(Err(err)) => {
735+
self.err = Some(err);
736+
None
737+
}
738+
None => None,
610739
}
611-
None => None,
612740
}
613741
}
614-
}
615742

616-
let mut adapter = Adapter { iter: iter, err: None };
617-
let v: V = FromIterator::from_iter(adapter.by_ref());
743+
let mut adapter = Adapter { iter: iter, err: None };
744+
let v: V = FromIterator::from_iter(adapter.by_ref());
618745

619-
match adapter.err {
620-
Some(err) => Err(err),
621-
None => Ok(v),
746+
match adapter.err {
747+
Some(err) => Err(err),
748+
None => Ok(v),
749+
}
622750
}
623751
}
624752

@@ -627,6 +755,7 @@ pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Ite
627755
/// If an `Err` is encountered, it is immediately returned.
628756
/// Otherwise, the folded value is returned.
629757
#[inline]
758+
#[experimental]
630759
pub fn fold<T,
631760
V,
632761
E,
@@ -644,12 +773,15 @@ pub fn fold<T,
644773
Ok(init)
645774
}
646775

776+
/// Deprecated.
777+
///
647778
/// Perform a trivial fold operation over the result values
648779
/// from an iterator.
649780
///
650781
/// If an `Err` is encountered, it is immediately returned.
651782
/// Otherwise, a simple `Ok(())` is returned.
652783
#[inline]
784+
#[deprecated = "use fold instead"]
653785
pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
654786
fold(iterator, (), |_, _| ())
655787
}

0 commit comments

Comments
 (0)