about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-09-11 09:33:45 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-09-12 18:54:12 -0700
commite03d60e9ebf2dbc2d18ab9919f905c17b967fcde (patch)
treed80ca6146eb66e930b1063c6929bb1b09e90b1e6 /src/libstd
parent12e0d7ecf061313d02a4647db8c1b30aad2ae53d (diff)
downloadrust-e03d60e9ebf2dbc2d18ab9919f905c17b967fcde.tar.gz
rust-e03d60e9ebf2dbc2d18ab9919f905c17b967fcde.zip
std: Add ToEither/IntoEither/AsEither
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/either.rs62
-rw-r--r--src/libstd/option.rs42
-rw-r--r--src/libstd/result.rs79
3 files changed, 162 insertions, 21 deletions
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index 526a5380dfb..27381f64ad4 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -105,6 +105,24 @@ impl<L, R> Either<L, R> {
     }
 }
 
+/// A generic trait for converting a value to a `Either`
+pub trait ToEither<L, R> {
+    /// Convert to the `either` type
+    fn to_either(&self) -> Either<L, R>;
+}
+
+/// A generic trait for converting a value to a `Either`
+pub trait IntoEither<L, R> {
+    /// Convert to the `either` type
+    fn into_either(self) -> Either<L, R>;
+}
+
+/// A generic trait for converting a value to a `Either`
+pub trait AsEither<L, R> {
+    /// Convert to the `either` type
+    fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>;
+}
+
 impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
     #[inline]
     fn to_option(&self)-> option::Option<R> {
@@ -165,6 +183,23 @@ impl<L, R> result::AsResult<R, L> for Either<L, R> {
     }
 }
 
+impl<L: Clone, R: Clone> ToEither<L, R> for Either<L, R> {
+    fn to_either(&self) -> Either<L, R> { self.clone() }
+}
+
+impl<L, R> IntoEither<L, R> for Either<L, R> {
+    fn into_either(self) -> Either<L, R> { self }
+}
+
+impl<L, R> AsEither<L, R> for Either<L, R> {
+    fn as_either<'a>(&'a self) -> Either<&'a L, &'a R> {
+        match *self {
+            Left(ref l) => Left(l),
+            Right(ref r) => Right(r),
+        }
+    }
+}
+
 /// An iterator yielding the `Left` values of its source
 pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
 
@@ -370,4 +405,31 @@ mod tests {
         let x = 404;
         assert_eq!(left.as_result(), result::Err(&x));
     }
+
+    #[test]
+    pub fn test_to_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.to_either(), Right(100));
+        assert_eq!(left.to_either(), Left(404));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.into_either(), Right(100));
+        assert_eq!(left.into_either(), Left(404));
+    }
+
+    #[test]
+    pub fn test_as_either() {
+        let right: Either<int, int> = Right(100);
+        let left: Either<int, int> = Left(404);
+
+        assert_eq!(right.as_either().unwrap_right(), &100);
+        assert_eq!(left.as_either().unwrap_left(), &404);
+    }
 }
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 83bc7856098..cd9e3980716 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -44,6 +44,7 @@ let unwrapped_msg = match msg {
 use clone::Clone;
 use cmp::{Eq,Ord};
 use default::Default;
+use either;
 use util;
 use num::Zero;
 use iter;
@@ -447,6 +448,26 @@ impl<T> result::IntoResult<T, ()> for Option<T> {
     }
 }
 
+impl<T: Clone> either::ToEither<(), T> for Option<T> {
+    #[inline]
+    fn to_either(&self) -> either::Either<(), T> {
+        match *self {
+            Some(ref x) => either::Right(x.clone()),
+            None => either::Left(()),
+        }
+    }
+}
+
+impl<T> either::IntoEither<(), T> for Option<T> {
+    #[inline]
+    fn into_either(self) -> either::Either<(), T> {
+        match self {
+            Some(x) => either::Right(x),
+            None => either::Left(()),
+        }
+    }
+}
+
 impl<T: Default> Option<T> {
     /// Returns the contained value or default (for this type)
     #[inline]
@@ -529,6 +550,9 @@ impl<A> ExactSize<A> for OptionIterator<A> {}
 #[cfg(test)]
 mod tests {
     use super::*;
+
+    use either::{IntoEither, ToEither};
+    use either;
     use result::{IntoResult, ToResult};
     use result;
     use util;
@@ -817,4 +841,22 @@ mod tests {
         assert_eq!(some.into_result(), result::Ok(100));
         assert_eq!(none.into_result(), result::Err(()));
     }
+
+    #[test]
+    pub fn test_to_either() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.to_either(), either::Right(100));
+        assert_eq!(none.to_either(), either::Left(()));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let some: Option<int> = Some(100);
+        let none: Option<int> = None;
+
+        assert_eq!(some.into_either(), either::Right(100));
+        assert_eq!(none.into_either(), either::Left(()));
+    }
 }
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index f6c2a39ccf0..20b65f1576d 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -37,18 +37,6 @@ pub enum Result<T, E> {
 }
 
 impl<T, E: ToStr> Result<T, E> {
-    /// Convert to the `either` type
-    ///
-    /// `Ok` result variants are converted to `either::Right` variants, `Err`
-    /// result variants are converted to `either::Left`.
-    #[inline]
-    pub fn to_either(self)-> either::Either<E, T>{
-        match self {
-            Ok(t) => either::Right(t),
-            Err(e) => either::Left(e),
-        }
-    }
-
     /// Get a reference to the value out of a successful result
     ///
     /// # Failure
@@ -324,6 +312,36 @@ impl<T, E> AsResult<T, E> for Result<T, E> {
     }
 }
 
+impl<T: Clone, E: Clone> either::ToEither<E, T> for Result<T, E> {
+    #[inline]
+    fn to_either(&self)-> either::Either<E, T> {
+        match *self {
+            Ok(ref t) => either::Right(t.clone()),
+            Err(ref e) => either::Left(e.clone()),
+        }
+    }
+}
+
+impl<T, E> either::IntoEither<E, T> for Result<T, E> {
+    #[inline]
+    fn into_either(self)-> either::Either<E, T> {
+        match self {
+            Ok(t) => either::Right(t),
+            Err(e) => either::Left(e),
+        }
+    }
+}
+
+impl<T, E> either::AsEither<E, T> for Result<T, E> {
+    #[inline]
+    fn as_either<'a>(&'a self)-> either::Either<&'a E, &'a T> {
+        match *self {
+            Ok(ref t) => either::Right(t),
+            Err(ref e) => either::Left(e),
+        }
+    }
+}
+
 #[inline]
 #[allow(missing_doc)]
 pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
@@ -403,6 +421,7 @@ pub fn fold_<T, E, Iter: Iterator<Result<T, E>>>(
 mod tests {
     use super::*;
 
+    use either::{IntoEither, ToEither, AsEither};
     use either;
     use iter::range;
     use option::{IntoOption, ToOption, AsOption};
@@ -484,15 +503,6 @@ mod tests {
     }
 
     #[test]
-    pub fn test_to_either() {
-        let r: Result<int, ()> = Ok(100);
-        let err: Result<(), int> = Err(404);
-
-        assert_eq!(r.to_either(), either::Right(100));
-        assert_eq!(err.to_either(), either::Left(404));
-    }
-
-    #[test]
     fn test_collect() {
         assert_eq!(collect(range(0, 0)
                            .map(|_| Ok::<int, ()>(0))),
@@ -588,4 +598,31 @@ mod tests {
         let x = 404;
         assert_eq!(err.as_result(), Err(&x));
     }
+
+    #[test]
+    pub fn test_to_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.to_either(), either::Right(100));
+        assert_eq!(err.to_either(), either::Left(404));
+    }
+
+    #[test]
+    pub fn test_into_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.into_either(), either::Right(100));
+        assert_eq!(err.into_either(), either::Left(404));
+    }
+
+    #[test]
+    pub fn test_as_either() {
+        let ok: Result<int, int> = Ok(100);
+        let err: Result<int, int> = Err(404);
+
+        assert_eq!(ok.as_either().unwrap_right(), &100);
+        assert_eq!(err.as_either().unwrap_left(), &404);
+    }
 }