about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAaron Turon <aturon@mozilla.com>2014-08-19 13:45:28 -0700
committerAaron Turon <aturon@mozilla.com>2014-08-28 09:12:54 -0700
commit9a8233d3772fbdb3d496aac3e4693e6d4c30e125 (patch)
treeccf71d4fc58395283399be7deba26d2f90ce7810 /src
parent276b8b125d3f60cebab702542b60207429fbb333 (diff)
downloadrust-9a8233d3772fbdb3d496aac3e4693e6d4c30e125.tar.gz
rust-9a8233d3772fbdb3d496aac3e4693e6d4c30e125.zip
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]
Diffstat (limited to 'src')
-rw-r--r--src/libcore/result.rs214
1 files changed, 173 insertions, 41 deletions
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 980a9c7506f..bf351ecc89b 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -274,10 +274,14 @@
 //! the context. The caller of `fail!` should assume that execution
 //! will not resume after failure, that failure is catastrophic.
 
+#![stable]
+
 use clone::Clone;
 use cmp::PartialEq;
 use std::fmt::Show;
-use iter::{Iterator, FromIterator};
+use slice;
+use slice::Slice;
+use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
 use option::{None, Option, Some};
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
@@ -285,6 +289,7 @@ use option::{None, Option, Some};
 /// See the [`std::result`](index.html) module documentation for details.
 #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
 #[must_use]
+#[stable]
 pub enum Result<T, E> {
     /// Contains the success value
     Ok(T),
@@ -315,6 +320,7 @@ impl<T, E> Result<T, E> {
     /// # }
     /// ~~~
     #[inline]
+    #[stable]
     pub fn is_ok(&self) -> bool {
         match *self {
             Ok(_) => true,
@@ -335,6 +341,7 @@ impl<T, E> Result<T, E> {
     /// assert!(bogus.is_err());
     /// ~~~
     #[inline]
+    #[stable]
     pub fn is_err(&self) -> bool {
         !self.is_ok()
     }
@@ -362,6 +369,7 @@ impl<T, E> Result<T, E> {
     /// let bdays: File = bdays.ok().expect("unable to open birthday file");
     /// ~~~
     #[inline]
+    #[stable]
     pub fn ok(self) -> Option<T> {
         match self {
             Ok(x)  => Some(x),
@@ -374,6 +382,7 @@ impl<T, E> Result<T, E> {
     /// Converts `self` into an `Option<T>`, consuming `self`,
     /// and discarding the value, if any.
     #[inline]
+    #[stable]
     pub fn err(self) -> Option<E> {
         match self {
             Ok(_)  => None,
@@ -390,6 +399,7 @@ impl<T, E> Result<T, E> {
     /// Produces a new `Result`, containing a reference
     /// into the original, leaving the original in place.
     #[inline]
+    #[stable]
     pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
         match *self {
             Ok(ref x) => Ok(x),
@@ -399,6 +409,7 @@ impl<T, E> Result<T, E> {
 
     /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
     #[inline]
+    #[unstable = "waiting for mut conventions"]
     pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
         match *self {
             Ok(ref mut x) => Ok(x),
@@ -406,6 +417,20 @@ impl<T, E> Result<T, E> {
         }
     }
 
+    /// Convert from `Result<T, E>` to `&mut [T]` (without copying)
+    #[inline]
+    #[unstable = "waiting for mut conventions"]
+    pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
+        match *self {
+            Ok(ref mut x) => slice::mut_ref_slice(x),
+            Err(_) => {
+                // work around lack of implicit coercion from fixed-size array to slice
+                let emp: &mut [_] = &mut [];
+                emp
+            }
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////
     // Transforming contained values
     /////////////////////////////////////////////////////////////////////////
@@ -441,6 +466,7 @@ impl<T, E> Result<T, E> {
     /// assert!(sum == 10);
     /// ~~~
     #[inline]
+    #[unstable = "waiting for unboxed closures"]
     pub fn map<U>(self, op: |T| -> U) -> Result<U,E> {
         match self {
           Ok(t) => Ok(op(t)),
@@ -454,6 +480,7 @@ impl<T, E> Result<T, E> {
     /// This function can be used to pass through a successful result while handling
     /// an error.
     #[inline]
+    #[unstable = "waiting for unboxed closures"]
     pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> {
         match self {
           Ok(t) => Ok(t),
@@ -461,12 +488,39 @@ impl<T, E> Result<T, E> {
         }
     }
 
+
+    /////////////////////////////////////////////////////////////////////////
+    // Iterator constructors
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Returns an iterator over the possibly contained value.
+    #[inline]
+    #[unstable = "waiting for iterator conventions"]
+    pub fn iter<'r>(&'r self) -> Item<&'r T> {
+        Item{opt: self.as_ref().ok()}
+    }
+
+    /// Returns a mutable iterator over the possibly contained value.
+    #[inline]
+    #[unstable = "waiting for iterator conventions"]
+    pub fn mut_iter<'r>(&'r mut self) -> Item<&'r mut T> {
+        Item{opt: self.as_mut().ok()}
+    }
+
+    /// Returns a consuming iterator over the possibly contained value.
+    #[inline]
+    #[unstable = "waiting for iterator conventions"]
+    pub fn move_iter(self) -> Item<T> {
+        Item{opt: self.ok()}
+    }
+
     ////////////////////////////////////////////////////////////////////////
     // Boolean operations on the values, eager and lazy
     /////////////////////////////////////////////////////////////////////////
 
     /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
     #[inline]
+    #[stable]
     pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
         match self {
             Ok(_) => res,
@@ -478,6 +532,7 @@ impl<T, E> Result<T, E> {
     ///
     /// This function can be used for control flow based on result values
     #[inline]
+    #[unstable = "waiting for unboxed closures"]
     pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> {
         match self {
             Ok(t) => op(t),
@@ -487,6 +542,7 @@ impl<T, E> Result<T, E> {
 
     /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
     #[inline]
+    #[stable]
     pub fn or(self, res: Result<T, E>) -> Result<T, E> {
         match self {
             Ok(_) => self,
@@ -498,6 +554,7 @@ impl<T, E> Result<T, E> {
     ///
     /// This function can be used for control flow based on result values
     #[inline]
+    #[unstable = "waiting for unboxed closures"]
     pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> {
         match self {
             Ok(t) => Ok(t),
@@ -508,6 +565,7 @@ impl<T, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     /// Else it returns `optb`.
     #[inline]
+    #[unstable = "waiting for conventions"]
     pub fn unwrap_or(self, optb: T) -> T {
         match self {
             Ok(t) => t,
@@ -518,6 +576,7 @@ impl<T, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     /// If the value is an `Err` then it calls `op` with its value.
     #[inline]
+    #[unstable = "waiting for conventions"]
     pub fn unwrap_or_else(self, op: |E| -> T) -> T {
         match self {
             Ok(t) => t,
@@ -541,6 +600,7 @@ impl<T, E: Show> Result<T, E> {
     /// Fails if the value is an `Err`, with a custom failure message provided
     /// by the `Err`'s value.
     #[inline]
+    #[unstable = "waiting for conventions"]
     pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
@@ -558,6 +618,7 @@ impl<T: Show, E> Result<T, E> {
     /// Fails if the value is an `Ok`, with a custom failure message provided
     /// by the `Ok`'s value.
     #[inline]
+    #[unstable = "waiting for conventions"]
     pub fn unwrap_err(self) -> E {
         match self {
             Ok(t) =>
@@ -568,57 +629,124 @@ impl<T: Show, E> Result<T, E> {
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// Free functions
+// Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
-/// Takes each element in the `Iterator`: if it is an `Err`, no further
-/// elements are taken, and the `Err` is returned. Should no `Err` occur, a
-/// vector containing the values of each `Result` is returned.
-///
-/// Here is an example which increments every integer in a vector,
-/// checking for overflow:
-///
-/// ```rust
-/// use std::result;
-/// use std::uint;
+impl<T, E> Slice<T> for Result<T, E> {
+    /// Convert from `Result<T, E>` to `&[T]` (without copying)
+    #[inline]
+    #[stable]
+    fn as_slice<'a>(&'a self) -> &'a [T] {
+        match *self {
+            Ok(ref x) => slice::ref_slice(x),
+            Err(_) => {
+                // work around lack of implicit coercion from fixed-size array to slice
+                let emp: &[_] = &[];
+                emp
+            }
+        }
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The Result Iterator
+/////////////////////////////////////////////////////////////////////////////
+
+/// A `Result` iterator that yields either one or zero elements
 ///
-/// let v = vec!(1u, 2u);
-/// let res: Result<Vec<uint>, &'static str> = result::collect(v.iter().map(|x: &uint|
-///     if *x == uint::MAX { Err("Overflow!") }
-///     else { Ok(x + 1) }
-/// ));
-/// assert!(res == Ok(vec!(2u, 3u)));
-/// ```
-#[inline]
-pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> {
-    // FIXME(#11084): This could be replaced with Iterator::scan when this
-    // performance bug is closed.
+/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter`
+/// methods on `Result`.
+#[deriving(Clone)]
+#[unstable = "waiting for iterator conventions"]
+pub struct Item<T> {
+    opt: Option<T>
+}
+
+impl<T> Iterator<T> for Item<T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.opt.take()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        match self.opt {
+            Some(_) => (1, Some(1)),
+            None => (0, Some(0)),
+        }
+    }
+}
 
-    struct Adapter<Iter, E> {
-        iter: Iter,
-        err: Option<E>,
+impl<A> DoubleEndedIterator<A> for Item<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.opt.take()
     }
+}
+
+impl<A> ExactSize<A> for Item<A> {}
 
-    impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> {
-        #[inline]
-        fn next(&mut self) -> Option<T> {
-            match self.iter.next() {
-                Some(Ok(value)) => Some(value),
-                Some(Err(err)) => {
-                    self.err = Some(err);
-                    None
+/////////////////////////////////////////////////////////////////////////////
+// Free functions
+/////////////////////////////////////////////////////////////////////////////
+
+/// Deprecated: use `Iterator::collect`.
+#[inline]
+#[deprecated = "use Iterator::collect instead"]
+pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(mut iter: Iter)
+                                                                       -> Result<V, E> {
+    iter.collect()
+}
+
+impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
+    /// Takes each element in the `Iterator`: if it is an `Err`, no further
+    /// elements are taken, and the `Err` is returned. Should no `Err` occur, a
+    /// container with the values of each `Result` is returned.
+    ///
+    /// Here is an example which increments every integer in a vector,
+    /// checking for overflow:
+    ///
+    /// ```rust
+    /// use std::uint;
+    ///
+    /// let v = vec!(1u, 2u);
+    /// let res: Result<Vec<uint>, &'static str> = v.iter().map(|x: &uint|
+    ///     if *x == uint::MAX { Err("Overflow!") }
+    ///     else { Ok(x + 1) }
+    /// ).collect();
+    /// assert!(res == Ok(vec!(2u, 3u)));
+    /// ```
+    #[inline]
+    fn from_iter<I: Iterator<Result<A, E>>>(iter: I) -> Result<V, E> {
+        // FIXME(#11084): This could be replaced with Iterator::scan when this
+        // performance bug is closed.
+
+        struct Adapter<Iter, E> {
+            iter: Iter,
+            err: Option<E>,
+        }
+
+        impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> {
+            #[inline]
+            fn next(&mut self) -> Option<T> {
+                match self.iter.next() {
+                    Some(Ok(value)) => Some(value),
+                    Some(Err(err)) => {
+                        self.err = Some(err);
+                        None
+                    }
+                    None => None,
                 }
-                None => None,
             }
         }
-    }
 
-    let mut adapter = Adapter { iter: iter, err: None };
-    let v: V = FromIterator::from_iter(adapter.by_ref());
+        let mut adapter = Adapter { iter: iter, err: None };
+        let v: V = FromIterator::from_iter(adapter.by_ref());
 
-    match adapter.err {
-        Some(err) => Err(err),
-        None => Ok(v),
+        match adapter.err {
+            Some(err) => Err(err),
+            None => Ok(v),
+        }
     }
 }
 
@@ -627,6 +755,7 @@ pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Ite
 /// If an `Err` is encountered, it is immediately returned.
 /// Otherwise, the folded value is returned.
 #[inline]
+#[experimental]
 pub fn fold<T,
             V,
             E,
@@ -644,12 +773,15 @@ pub fn fold<T,
     Ok(init)
 }
 
+/// Deprecated.
+///
 /// Perform a trivial fold operation over the result values
 /// from an iterator.
 ///
 /// If an `Err` is encountered, it is immediately returned.
 /// Otherwise, a simple `Ok(())` is returned.
 #[inline]
+#[deprecated = "use fold instead"]
 pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> {
     fold(iterator, (), |_, _| ())
 }