Skip to content

Commit

Permalink
auto merge of #19961 : alexcrichton/rust/second-pass-result, r=aturon
Browse files Browse the repository at this point in the history
This commit, like the second pass of `Option`, largely just stablizes the
existing functionality after renaming a few iterators.

The specific actions taken were:

* The `Ok` and `Err` variants were marked `#[stable]` as the stability
  inheritance was since removed.
* The `as_mut` method is now stable.
* The `map` method is now stable
* The `map_err` method is now stable
* The `iter`, `iter_mut`, and `into_iter` methods now returned structures named
  after the method of iteration. The methods are also now all stable.
* The `and_then` method is now stable.
* The `or_else` method is now stable.
* The `unwrap` family of functions are now all stable: `unwrap_or`,
  `unwrap_or_else`, `unwrap`, and `unwrap_err`.

There is a possible open extension to `Result::{and, and_then}` to make the
return type further generic over `FromError` (as proposed in #19078), but this
is a backwards compatible change due to the usage of default type parameters,
which makes the two functions safe to stabilize now regardless of the outcome of
that issue.
  • Loading branch information
bors committed Dec 21, 2014
2 parents c141f22 + a71686f commit 1bdcfd6
Showing 1 changed file with 90 additions and 54 deletions.
144 changes: 90 additions & 54 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,15 @@

#![stable]

use self::Result::*;
use self::Result::{Ok, Err};

use std::fmt::Show;
use slice;
use slice::AsSlice;
use clone::Clone;
use fmt::Show;
use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
use option::Option;
use option::Option::{None, Some};
use ops::{FnMut, FnOnce};
use option::Option::{mod, None, Some};
use slice::AsSlice;
use slice;

/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
///
Expand All @@ -248,16 +248,19 @@ use ops::{FnMut, FnOnce};
#[stable]
pub enum Result<T, E> {
/// Contains the success value
#[stable]
Ok(T),

/// Contains the error value
#[stable]
Err(E)
}

/////////////////////////////////////////////////////////////////////////////
// Type implementation
/////////////////////////////////////////////////////////////////////////////

#[stable]
impl<T, E> Result<T, E> {
/////////////////////////////////////////////////////////////////////////
// Querying the contained values
Expand Down Expand Up @@ -300,7 +303,6 @@ impl<T, E> Result<T, E> {
!self.is_ok()
}


/////////////////////////////////////////////////////////////////////////
// Adapter for each variant
/////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -369,7 +371,7 @@ impl<T, E> Result<T, E> {
/// ```
#[inline]
#[stable]
pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
pub fn as_ref(&self) -> Result<&T, &E> {
match *self {
Ok(ref x) => Ok(x),
Err(ref x) => Err(x),
Expand All @@ -395,8 +397,8 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.unwrap_err(), 0);
/// ```
#[inline]
#[unstable = "waiting for mut conventions"]
pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
#[stable]
pub fn as_mut(&mut self) -> Result<&mut T, &mut E> {
match *self {
Ok(ref mut x) => Ok(x),
Err(ref mut x) => Err(x),
Expand All @@ -420,7 +422,7 @@ impl<T, E> Result<T, E> {
/// ```
#[inline]
#[unstable = "waiting for mut conventions"]
pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
pub fn as_mut_slice(&mut self) -> &mut [T] {
match *self {
Ok(ref mut x) => slice::mut_ref_slice(x),
Err(_) => {
Expand Down Expand Up @@ -465,11 +467,11 @@ impl<T, E> Result<T, E> {
/// assert!(sum == 10);
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> {
match self {
Ok(t) => Ok(op(t)),
Err(e) => Err(e)
Ok(t) => Ok(op(t)),
Err(e) => Err(e)
}
}

Expand All @@ -491,15 +493,14 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.map_err(stringify), Err("error code: 13".to_string()));
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(op(e))
Ok(t) => Ok(t),
Err(e) => Err(op(e))
}
}


/////////////////////////////////////////////////////////////////////////
// Iterator constructors
/////////////////////////////////////////////////////////////////////////
Expand All @@ -516,9 +517,9 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.iter().next(), None);
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn iter<'r>(&'r self) -> Item<&'r T> {
Item{opt: self.as_ref().ok()}
#[stable]
pub fn iter(&self) -> Iter<T> {
Iter { inner: self.as_ref().ok() }
}

/// Returns a mutable iterator over the possibly contained value.
Expand All @@ -537,9 +538,9 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.iter_mut().next(), None);
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn iter_mut<'r>(&'r mut self) -> Item<&'r mut T> {
Item{opt: self.as_mut().ok()}
#[stable]
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut { inner: self.as_mut().ok() }
}

/// Returns a consuming iterator over the possibly contained value.
Expand All @@ -556,9 +557,9 @@ impl<T, E> Result<T, E> {
/// assert_eq!(v, vec![]);
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn into_iter(self) -> Item<T> {
Item{opt: self.ok()}
#[stable]
pub fn into_iter(self) -> IntoIter<T> {
IntoIter { inner: self.ok() }
}

////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -611,7 +612,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3));
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
match self {
Ok(t) => op(t),
Expand Down Expand Up @@ -665,7 +666,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(Err(3).or_else(err).or_else(err), Err(3));
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
match self {
Ok(t) => Ok(t),
Expand All @@ -687,7 +688,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(x.unwrap_or(optb), optb);
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_or(self, optb: T) -> T {
match self {
Ok(t) => t,
Expand All @@ -707,7 +708,7 @@ impl<T, E> Result<T, E> {
/// assert_eq!(Err("foo").unwrap_or_else(count), 3u);
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
match self {
Ok(t) => t,
Expand All @@ -716,6 +717,7 @@ impl<T, E> Result<T, E> {
}
}

#[stable]
impl<T, E: Show> Result<T, E> {
/// Unwraps a result, yielding the content of an `Ok`.
///
Expand All @@ -736,7 +738,7 @@ impl<T, E: Show> Result<T, E> {
/// x.unwrap(); // panics with `emergency failure`
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap(self) -> T {
match self {
Ok(t) => t,
Expand All @@ -746,6 +748,7 @@ impl<T, E: Show> Result<T, E> {
}
}

#[stable]
impl<T: Show, E> Result<T, E> {
/// Unwraps a result, yielding the content of an `Err`.
///
Expand All @@ -766,7 +769,7 @@ impl<T: Show, E> Result<T, E> {
/// assert_eq!(x.unwrap_err(), "emergency failure");
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_err(self) -> E {
match self {
Ok(t) =>
Expand Down Expand Up @@ -797,42 +800,75 @@ impl<T, E> AsSlice<T> for Result<T, E> {
}

/////////////////////////////////////////////////////////////////////////////
// The Result Iterator
// The Result Iterators
/////////////////////////////////////////////////////////////////////////////

/// A `Result` iterator that yields either one or zero elements
///
/// The `Item` iterator is returned by the `iter`, `iter_mut` and `into_iter`
/// methods on `Result`.
#[deriving(Clone)]
#[unstable = "waiting for iterator conventions"]
pub struct Item<T> {
opt: Option<T>
}
/// An iterator over a reference to the `Ok` variant of a `Result`.
#[stable]
pub struct Iter<'a, T: 'a> { inner: Option<&'a T> }

impl<T> Iterator<T> for Item<T> {
impl<'a, T> Iterator<&'a T> for Iter<'a, T> {
#[inline]
fn next(&mut self) -> Option<T> {
self.opt.take()
fn next(&mut self) -> Option<&'a T> { self.inner.take() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let n = if self.inner.is_some() {1} else {0};
(n, Some(n))
}
}

impl<'a, T> DoubleEndedIterator<&'a T> for Iter<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a T> { self.inner.take() }
}

impl<'a, T> ExactSizeIterator<&'a T> for Iter<'a, T> {}

impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } }
}

/// An iterator over a mutable reference to the `Ok` variant of a `Result`.
#[stable]
pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> }

impl<'a, T> Iterator<&'a mut T> for IterMut<'a, T> {
#[inline]
fn next(&mut self) -> Option<&'a mut T> { self.inner.take() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
match self.opt {
Some(_) => (1, Some(1)),
None => (0, Some(0)),
}
let n = if self.inner.is_some() {1} else {0};
(n, Some(n))
}
}

impl<A> DoubleEndedIterator<A> for Item<A> {
impl<'a, T> DoubleEndedIterator<&'a mut T> for IterMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<A> {
self.opt.take()
fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() }
}

impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {}

/// An iterator over the value in a `Ok` variant of a `Result`.
#[stable]
pub struct IntoIter<T> { inner: Option<T> }

impl<T> Iterator<T> for IntoIter<T> {
#[inline]
fn next(&mut self) -> Option<T> { self.inner.take() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let n = if self.inner.is_some() {1} else {0};
(n, Some(n))
}
}

impl<A> ExactSizeIterator<A> for Item<A> {}
impl<T> DoubleEndedIterator<T> for IntoIter<T> {
#[inline]
fn next_back(&mut self) -> Option<T> { self.inner.take() }
}

impl<T> ExactSizeIterator<T> for IntoIter<T> {}

/////////////////////////////////////////////////////////////////////////////
// FromIterator
Expand Down

0 comments on commit 1bdcfd6

Please sign in to comment.