From e03d60e9ebf2dbc2d18ab9919f905c17b967fcde Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 11 Sep 2013 09:33:45 -0700 Subject: std: Add ToEither/IntoEither/AsEither --- src/libstd/either.rs | 62 +++++++++++++++++++++++++++++++++++++++++ src/libstd/option.rs | 42 ++++++++++++++++++++++++++++ src/libstd/result.rs | 79 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 162 insertions(+), 21 deletions(-) (limited to 'src/libstd') 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 Either { } } +/// A generic trait for converting a value to a `Either` +pub trait ToEither { + /// Convert to the `either` type + fn to_either(&self) -> Either; +} + +/// A generic trait for converting a value to a `Either` +pub trait IntoEither { + /// Convert to the `either` type + fn into_either(self) -> Either; +} + +/// A generic trait for converting a value to a `Either` +pub trait AsEither { + /// Convert to the `either` type + fn as_either<'a>(&'a self) -> Either<&'a L, &'a R>; +} + impl option::ToOption for Either { #[inline] fn to_option(&self)-> option::Option { @@ -165,6 +183,23 @@ impl result::AsResult for Either { } } +impl ToEither for Either { + fn to_either(&self) -> Either { self.clone() } +} + +impl IntoEither for Either { + fn into_either(self) -> Either { self } +} + +impl AsEither for Either { + 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 = FilterMap<'static, Either, 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 = Right(100); + let left: Either = 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 = Right(100); + let left: Either = 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 = Right(100); + let left: Either = 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 result::IntoResult for Option { } } +impl either::ToEither<(), T> for Option { + #[inline] + fn to_either(&self) -> either::Either<(), T> { + match *self { + Some(ref x) => either::Right(x.clone()), + None => either::Left(()), + } + } +} + +impl either::IntoEither<(), T> for Option { + #[inline] + fn into_either(self) -> either::Either<(), T> { + match self { + Some(x) => either::Right(x), + None => either::Left(()), + } + } +} + impl Option { /// Returns the contained value or default (for this type) #[inline] @@ -529,6 +550,9 @@ impl ExactSize for OptionIterator {} #[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 = Some(100); + let none: Option = 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 = Some(100); + let none: Option = 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 { } impl Result { - /// 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{ - 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 AsResult for Result { } } +impl either::ToEither for Result { + #[inline] + fn to_either(&self)-> either::Either { + match *self { + Ok(ref t) => either::Right(t.clone()), + Err(ref e) => either::Left(e.clone()), + } + } +} + +impl either::IntoEither for Result { + #[inline] + fn into_either(self)-> either::Either { + match self { + Ok(t) => either::Right(t), + Err(e) => either::Left(e), + } + } +} + +impl either::AsEither for Result { + #[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(o_t: &Option, @@ -403,6 +421,7 @@ pub fn fold_>>( mod tests { use super::*; + use either::{IntoEither, ToEither, AsEither}; use either; use iter::range; use option::{IntoOption, ToOption, AsOption}; @@ -483,15 +502,6 @@ mod tests { assert_eq!(*foo.get_ref(), 100); } - #[test] - pub fn test_to_either() { - let r: Result = 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) @@ -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 = Ok(100); + let err: Result = 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 = Ok(100); + let err: Result = 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 = Ok(100); + let err: Result = Err(404); + + assert_eq!(ok.as_either().unwrap_right(), &100); + assert_eq!(err.as_either().unwrap_left(), &404); + } } -- cgit 1.4.1-3-g733a5