about summary refs log tree commit diff
path: root/src/libstd/result.rs
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2013-10-31 23:09:24 +0100
committerMarvin Löbel <loebel.marvin@gmail.com>2013-11-01 15:00:46 +0100
commit0d92c53f4a5707ee994d74d9e96995d7bac2ab13 (patch)
tree4ecff877b97d43c3f1ce5666cbd6a9630648eb8c /src/libstd/result.rs
parent04c58c9f81c5d9b6b1847573a41c8b819893a12a (diff)
downloadrust-0d92c53f4a5707ee994d74d9e96995d7bac2ab13.tar.gz
rust-0d92c53f4a5707ee994d74d9e96995d7bac2ab13.zip
Reordered the methods in std::Option and std::Result
Cleaned up the source in a few places

Renamed `map_move` to `map`, removed other `map` methods

Added `as_ref` and `as_mut` adapters to `Result`

Added `fmt::Default` impl
Diffstat (limited to 'src/libstd/result.rs')
-rw-r--r--src/libstd/result.rs323
1 files changed, 154 insertions, 169 deletions
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 957ba4a0438..cf2fa4468e7 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -10,19 +10,18 @@
 
 //! A type representing either success or failure
 
-#[allow(missing_doc)];
-
+use any::Any;
 use clone::Clone;
 use cmp::Eq;
 use either;
+use fmt;
 use iter::Iterator;
+use kinds::Send;
 use option::{None, Option, Some, OptionIterator};
 use option;
-use vec;
-use vec::OwnedVector;
 use to_str::ToStr;
-use str::StrSlice;
-use fmt;
+use vec::OwnedVector;
+use vec;
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
@@ -37,20 +36,14 @@ pub enum Result<T, E> {
     Err(E)
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// Type implementation
+/////////////////////////////////////////////////////////////////////////////
+
 impl<T, E: ToStr> Result<T, E> {
-    /// Get a reference to the value out of a successful result
-    ///
-    /// # Failure
-    ///
-    /// If the result is an error
-    #[inline]
-    pub fn get_ref<'a>(&'a self) -> &'a T {
-        match *self {
-            Ok(ref t) => t,
-            Err(ref e) => fail!("called `Result::get_ref()` on `Err` value: {}",
-                                 e.to_str()),
-        }
-    }
+    /////////////////////////////////////////////////////////////////////////
+    // Querying the contained values
+    /////////////////////////////////////////////////////////////////////////
 
     /// Returns true if the result is `Ok`
     #[inline]
@@ -67,137 +60,153 @@ impl<T, E: ToStr> Result<T, E> {
         !self.is_ok()
     }
 
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Ok` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is returned. if `self` is `Err` then it is
-    /// immediately returned. This function can be used to compose the results
-    /// of two functions.
-    ///
-    /// Example:
-    ///
-    ///     for buf in read_file(file) {
-    ///         print_buf(buf)
-    ///     }
+    /////////////////////////////////////////////////////////////////////////
+    // Adapter for working with references
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Convert from `Result<T, E>` to `Result<&T, &E>`
     #[inline]
-    pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
+    pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> {
         match *self {
-            Ok(ref t) => Some(t),
-            Err(*) => None,
-        }.move_iter()
+            Ok(ref x) => Ok(x),
+            Err(ref x) => Err(x),
+        }
     }
 
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Err` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is returned. if `self` is `Ok` then it is
-    /// immediately returned.  This function can be used to pass through a
-    /// successful result while handling an error.
+    /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
     #[inline]
-    pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
+    pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> {
         match *self {
-            Ok(*) => None,
-            Err(ref t) => Some(t),
-        }.move_iter()
+            Ok(ref mut x) => Ok(x),
+            Err(ref mut x) => Err(x),
+        }
     }
 
+    /////////////////////////////////////////////////////////////////////////
+    // Getting to contained values
+    /////////////////////////////////////////////////////////////////////////
+
     /// Unwraps a result, yielding the content of an `Ok`.
-    /// Fails if the value is a `Err` with an error message derived
-    /// from `E`'s `ToStr` implementation.
+    /// Fails if the value is a `Err` with a custom failure message provided by `msg`.
     #[inline]
-    pub fn unwrap(self) -> T {
+    pub fn expect<M: Any + Send>(self, msg: M) -> T {
         match self {
             Ok(t) => t,
-            Err(e) => fail!("called `Result::unwrap()` on `Err` value: {}",
-                             e.to_str()),
+            Err(_) => fail!(msg),
         }
     }
 
     /// Unwraps a result, yielding the content of an `Err`.
-    /// Fails if the value is a `Ok`.
+    /// Fails if the value is a `Ok` with a custom failure message provided by `msg`.
     #[inline]
-    pub fn unwrap_err(self) -> E {
-        self.expect_err("called `Result::unwrap_err()` on `Ok` value")
+    pub fn expect_err<M: Any + Send>(self, msg: M) -> E {
+        match self {
+            Err(e) => e,
+            Ok(_) => fail!(msg),
+        }
     }
 
     /// Unwraps a result, yielding the content of an `Ok`.
-    /// Fails if the value is a `Err` with a custom failure message.
+    /// Fails if the value is a `Err` with an error message derived
+    /// from `E`'s `ToStr` implementation.
     #[inline]
-    pub fn expect(self, reason: &str) -> T {
+    pub fn unwrap(self) -> T {
         match self {
             Ok(t) => t,
-            Err(_) => fail!("{}", reason.to_owned()),
+            Err(e) => fail!("called `Result::unwrap()` on `Err` value '{}'",
+                             e.to_str()),
         }
     }
 
-    /// Unwraps a result, yielding the content of an `Err`
-    /// Fails if the value is a `Ok` with a custom failure message.
+    /// Unwraps a result, yielding the content of an `Err`.
+    /// Fails if the value is a `Ok`.
     #[inline]
-    pub fn expect_err(self, reason: &str) -> E {
+    pub fn unwrap_err(self) -> E {
         match self {
-            Err(e) => e,
-            Ok(_) => fail!("{}", reason.to_owned()),
+            Ok(_) => fail!("called `Result::unwrap_err()` on an `Ok` value"),
+            Err(e) => e
         }
     }
 
-    /// Call a method based on a previous result
+    /////////////////////////////////////////////////////////////////////////
+    // Transforming contained values
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Maps an `Result<T, E>` to `Result<U, E>` by applying a function to an
+    /// contained `Ok` value, leaving an `Err` value untouched.
     ///
-    /// If `self` is `Ok` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
-    /// `Err` then it is immediately returned.  This function can be used to
-    /// compose the results of two functions.
+    /// This function can be used to compose the results of two functions.
     ///
     /// Example:
     ///
-    ///     let res = do read_file(file).map_move |buf| {
+    ///     let res = do read_file(file).map |buf| {
     ///         parse_bytes(buf)
     ///     }
     #[inline]
-    pub fn map_move<U>(self, op: &fn(T) -> U) -> Result<U,E> {
+    pub fn map<U>(self, op: &fn(T) -> U) -> Result<U,E> {
         match self {
           Ok(t) => Ok(op(t)),
           Err(e) => Err(e)
         }
     }
 
-    /// Call a method based on a previous result
+    /// Maps an `Result<T, E>` to `Result<T, F>` by applying a function to an
+    /// contained `Err` value, leaving an `Ok` value untouched.
     ///
-    /// If `self` is `Err` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
-    /// `Ok` then it is immediately returned.  This function can be used to pass
-    /// through a successful result while handling an error.
+    /// This function can be used to pass through a successful result while handling
+    /// an error.
     #[inline]
-    pub fn map_err_move<F>(self, op: &fn(E) -> F) -> Result<T,F> {
+    pub fn map_err<F>(self, op: &fn(E) -> F) -> Result<T,F> {
         match self {
           Ok(t) => Ok(t),
           Err(e) => Err(op(e))
         }
     }
 
-    /// Call a method based on a previous result
+    /////////////////////////////////////////////////////////////////////////
+    // Iterator constructors
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Returns an `Iterator` over one or zero references to the value of an `Ok`
     ///
-    /// If `self` is `Ok`, then `res` it is returned. If `self` is `Err`,
-    /// then `self` is returned.
+    /// Example:
+    ///
+    ///     for buf in read_file(file) {
+    ///         print_buf(buf)
+    ///     }
     #[inline]
-    pub fn and(self, res: Result<T, E>) -> Result<T, E> {
+    pub fn iter<'r>(&'r self) -> OptionIterator<&'r T> {
+        match *self {
+            Ok(ref t) => Some(t),
+            Err(*) => None,
+        }.move_iter()
+    }
+
+    /// Returns an `Iterator` over one or zero references to the value of an `Err`
+    #[inline]
+    pub fn iter_err<'r>(&'r self) -> OptionIterator<&'r E> {
+        match *self {
+            Ok(*) => None,
+            Err(ref t) => Some(t),
+        }.move_iter()
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    // Boolean operations on the values, eager and lazy
+    /////////////////////////////////////////////////////////////////////////
+
+    /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
+    #[inline]
+    pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
         match self {
             Ok(_) => res,
-            Err(_) => self,
+            Err(e) => Err(e),
         }
     }
 
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Ok` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is returned. If `self` is `Err` then it is
-    /// immediately returned. This function can be used to compose the results
-    /// of two functions.
+    /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`.
     ///
-    /// Example:
-    ///
-    ///     let res = do read_file(file) |buf| {
-    ///         Ok(parse_bytes(buf))
-    ///     };
+    /// This function can be used for control flow based on result values
     #[inline]
     pub fn and_then<U>(self, op: &fn(T) -> Result<U, E>) -> Result<U, E> {
         match self {
@@ -206,10 +215,7 @@ impl<T, E: ToStr> Result<T, E> {
         }
     }
 
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Ok`, then `self` is returned. If `self` is `Err`
-    /// then `res` is returned.
+    /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
     #[inline]
     pub fn or(self, res: Result<T, E>) -> Result<T, E> {
         match self {
@@ -218,12 +224,9 @@ impl<T, E: ToStr> Result<T, E> {
         }
     }
 
-    /// Call a function based on a previous result
+    /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`.
     ///
-    /// If `self` is `Err` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is returned. if `self` is `Ok` then it is
-    /// immediately returned.  This function can be used to pass through a
-    /// successful result while handling an error.
+    /// This function can be used for control flow based on result values
     #[inline]
     pub fn or_else<F>(self, op: &fn(E) -> Result<T, F>) -> Result<T, F> {
         match self {
@@ -231,46 +234,30 @@ impl<T, E: ToStr> Result<T, E> {
             Err(e) => op(e),
         }
     }
-}
 
-impl<T: Clone, E: ToStr> Result<T, E> {
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Err` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
-    /// `Ok` then it is immediately returned.  This function can be used to pass
-    /// through a successful result while handling an error.
-    #[inline]
-    pub fn map_err<F: Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
-        match *self {
-            Ok(ref t) => Ok(t.clone()),
-            Err(ref e) => Err(op(e))
-        }
-    }
-}
+    /////////////////////////////////////////////////////////////////////////
+    // Common special cases
+    /////////////////////////////////////////////////////////////////////////
 
-impl<T, E: Clone + ToStr> Result<T, E> {
-    /// Call a method based on a previous result
-    ///
-    /// If `self` is `Ok` then the value is extracted and passed to `op`
-    /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
-    /// `Err` then it is immediately returned.  This function can be used to
-    /// compose the results of two functions.
+    /// Get a reference to the value out of a successful result
     ///
-    /// Example:
+    /// # Failure
     ///
-    ///     let res = do read_file(file).map |buf| {
-    ///         parse_bytes(buf)
-    ///     };
+    /// If the result is an error
     #[inline]
-    pub fn map<U>(&self, op: &fn(&T) -> U) -> Result<U,E> {
+    pub fn get_ref<'a>(&'a self) -> &'a T {
         match *self {
-            Ok(ref t) => Ok(op(t)),
-            Err(ref e) => Err(e.clone())
+            Ok(ref t) => t,
+            Err(ref e) => fail!("called `Result::get_ref()` on `Err` value '{}'",
+                                 e.to_str()),
         }
     }
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// Constructor extension trait
+/////////////////////////////////////////////////////////////////////////////
+
 /// A generic trait for converting a value to a `Result`
 pub trait ToResult<T, E> {
     /// Convert to the `result` type
@@ -289,6 +276,30 @@ pub trait AsResult<T, E> {
     fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
 }
 
+impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
+    #[inline]
+    fn to_result(&self) -> Result<T, E> { self.clone() }
+}
+
+impl<T, E> IntoResult<T, E> for Result<T, E> {
+    #[inline]
+    fn into_result(self) -> Result<T, E> { self }
+}
+
+impl<T, E> AsResult<T, E> for Result<T, E> {
+    #[inline]
+    fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
+        match *self {
+            Ok(ref t) => Ok(t),
+            Err(ref e) => Err(e),
+        }
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Trait implementations
+/////////////////////////////////////////////////////////////////////////////
+
 impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
     #[inline]
     fn to_option(&self) -> Option<T> {
@@ -319,26 +330,6 @@ impl<T, E> option::AsOption<T> for Result<T, E> {
     }
 }
 
-impl<T: Clone, E: Clone> ToResult<T, E> for Result<T, E> {
-    #[inline]
-    fn to_result(&self) -> Result<T, E> { self.clone() }
-}
-
-impl<T, E> IntoResult<T, E> for Result<T, E> {
-    #[inline]
-    fn into_result(self) -> Result<T, E> { self }
-}
-
-impl<T, E> AsResult<T, E> for Result<T, E> {
-    #[inline]
-    fn as_result<'a>(&'a self) -> Result<&'a T, &'a E> {
-        match *self {
-            Ok(ref t) => Ok(t),
-            Err(ref e) => Err(e),
-        }
-    }
-}
-
 impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
     #[inline]
     fn to_either(&self) -> either::Either<E, T> {
@@ -389,6 +380,10 @@ impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
     }
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// Free functions
+/////////////////////////////////////////////////////////////////////////////
+
 /// Takes each element in the iterator: if it is an error, no further
 /// elements are taken, and the error is returned.
 /// Should no error occur, a vector containing the values of each Result
@@ -450,6 +445,9 @@ pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
     fold(iterator, (), |_, _| ())
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// Tests
+/////////////////////////////////////////////////////////////////////////////
 
 #[cfg(test)]
 mod tests {
@@ -460,7 +458,6 @@ mod tests {
     use iter::range;
     use option::{IntoOption, ToOption, AsOption};
     use option;
-    use str::OwnedStr;
     use vec::ImmutableVector;
     use to_str::ToStr;
 
@@ -470,10 +467,10 @@ mod tests {
     #[test]
     pub fn test_and() {
         assert_eq!(op1().and(Ok(667)).unwrap(), 667);
-        assert_eq!(op1().and(Err(~"bad")).unwrap_err(), ~"bad");
+        assert_eq!(op1().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"bad");
 
         assert_eq!(op2().and(Ok(667)).unwrap_err(), ~"sadface");
-        assert_eq!(op2().and(Err(~"bad")).unwrap_err(), ~"sadface");
+        assert_eq!(op2().and(Err::<(), ~str>(~"bad")).unwrap_err(), ~"sadface");
     }
 
     #[test]
@@ -530,26 +527,14 @@ mod tests {
 
     #[test]
     pub fn test_impl_map() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Ok(~"ba"));
-        assert_eq!(Err::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Err(~"a"));
+        assert_eq!(Ok::<~str, ~str>(~"a").map(|x| x + "b"), Ok(~"ab"));
+        assert_eq!(Err::<~str, ~str>(~"a").map(|x| x + "b"), Err(~"a"));
     }
 
     #[test]
     pub fn test_impl_map_err() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Ok(~"a"));
-        assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Err(~"ba"));
-    }
-
-    #[test]
-    pub fn test_impl_map_move() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map_move(|x| x + "b"), Ok(~"ab"));
-        assert_eq!(Err::<~str, ~str>(~"a").map_move(|x| x + "b"), Err(~"a"));
-    }
-
-    #[test]
-    pub fn test_impl_map_err_move() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Ok(~"a"));
-        assert_eq!(Err::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Err(~"ab"));
+        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| x + "b"), Ok(~"a"));
+        assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| x + "b"), Err(~"ab"));
     }
 
     #[test]