std: Add ToResult/IntoResult/AsResult

This commit is contained in:
Erick Tryzelaar 2013-09-11 09:32:09 -07:00
parent ff34740a29
commit 12e0d7ecf0
3 changed files with 171 additions and 12 deletions

View File

@ -54,18 +54,6 @@ impl<L, R> Either<L, R> {
}
}
/// Converts a `Either` to a `Result`
///
/// Converts an `Either` type to a `Result` type, making the "right" choice
/// an `Ok` result, and the "left" choice a `Err`
#[inline]
pub fn to_result(self) -> Result<R, L> {
match self {
Right(r) => result::Ok(r),
Left(l) => result::Err(l)
}
}
/// Checks whether the given value is a `Left`
#[inline]
pub fn is_left(&self) -> bool {
@ -147,6 +135,36 @@ impl<L, R> option::AsOption<R> for Either<L, R> {
}
}
impl<L: Clone, R: Clone> result::ToResult<R, L> for Either<L, R> {
#[inline]
fn to_result(&self)-> result::Result<R, L> {
match *self {
Left(ref l) => result::Err(l.clone()),
Right(ref r) => result::Ok(r.clone()),
}
}
}
impl<L, R> result::IntoResult<R, L> for Either<L, R> {
#[inline]
fn into_result(self)-> result::Result<R, L> {
match self {
Left(l) => result::Err(l),
Right(r) => result::Ok(r),
}
}
}
impl<L, R> result::AsResult<R, L> for Either<L, R> {
#[inline]
fn as_result<'a>(&'a self) -> result::Result<&'a R, &'a L> {
match *self {
Left(ref l) => result::Err(l),
Right(ref r) => result::Ok(r),
}
}
}
/// An iterator yielding the `Left` values of its source
pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
@ -200,6 +218,8 @@ mod tests {
use option::{IntoOption, ToOption, AsOption};
use option;
use result::{IntoResult, ToResult, AsResult};
use result;
#[test]
fn test_either_left() {
@ -320,4 +340,34 @@ mod tests {
assert_eq!(right.as_option().unwrap(), &100);
assert_eq!(left.as_option(), option::None);
}
#[test]
pub fn test_to_result() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
assert_eq!(right.to_result(), result::Ok(100));
assert_eq!(left.to_result(), result::Err(404));
}
#[test]
pub fn test_into_result() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
assert_eq!(right.into_result(), result::Ok(100));
assert_eq!(left.into_result(), result::Err(404));
}
#[test]
pub fn test_as_result() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
let x = 100;
assert_eq!(right.as_result(), result::Ok(&x));
let x = 404;
assert_eq!(left.as_result(), result::Err(&x));
}
}

View File

@ -48,6 +48,7 @@ use util;
use num::Zero;
use iter;
use iter::{Iterator, DoubleEndedIterator, ExactSize};
use result;
use str::{StrSlice, OwnedStr};
use to_str::ToStr;
use clone::DeepClone;
@ -426,6 +427,26 @@ impl<T> AsOption<T> for Option<T> {
}
}
impl<T: Clone> result::ToResult<T, ()> for Option<T> {
#[inline]
fn to_result(&self) -> result::Result<T, ()> {
match *self {
Some(ref x) => result::Ok(x.clone()),
None => result::Err(()),
}
}
}
impl<T> result::IntoResult<T, ()> for Option<T> {
#[inline]
fn into_result(self) -> result::Result<T, ()> {
match self {
Some(x) => result::Ok(x),
None => result::Err(()),
}
}
}
impl<T: Default> Option<T> {
/// Returns the contained value or default (for this type)
#[inline]
@ -508,6 +529,8 @@ impl<A> ExactSize<A> for OptionIterator<A> {}
#[cfg(test)]
mod tests {
use super::*;
use result::{IntoResult, ToResult};
use result;
use util;
#[test]
@ -776,4 +799,22 @@ mod tests {
assert_eq!(some.as_option().unwrap(), &100);
assert_eq!(none.as_option(), None);
}
#[test]
pub fn test_to_result() {
let some: Option<int> = Some(100);
let none: Option<int> = None;
assert_eq!(some.to_result(), result::Ok(100));
assert_eq!(none.to_result(), result::Err(()));
}
#[test]
pub fn test_into_result() {
let some: Option<int> = Some(100);
let none: Option<int> = None;
assert_eq!(some.into_result(), result::Ok(100));
assert_eq!(none.into_result(), result::Err(()));
}
}

View File

@ -256,6 +256,24 @@ impl<T, E: Clone + ToStr> Result<T, E> {
}
}
/// A generic trait for converting a value to a `Result`
pub trait ToResult<T, E> {
/// Convert to the `result` type
fn to_result(&self) -> Result<T, E>;
}
/// A generic trait for converting a value to a `Result`
pub trait IntoResult<T, E> {
/// Convert to the `result` type
fn into_result(self) -> Result<T, E>;
}
/// A generic trait for converting a value to a `Result`
pub trait AsResult<T, E> {
/// Convert to the `result` type
fn as_result<'a>(&'a self) -> Result<&'a T, &'a E>;
}
impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
#[inline]
fn to_option(&self)-> Option<T> {
@ -286,6 +304,26 @@ 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),
}
}
}
#[inline]
#[allow(missing_doc)]
pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
@ -520,4 +558,34 @@ mod tests {
assert_eq!(ok.as_option().unwrap(), &100);
assert_eq!(err.as_option(), option::None);
}
#[test]
pub fn test_to_result() {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
assert_eq!(ok.to_result(), Ok(100));
assert_eq!(err.to_result(), Err(404));
}
#[test]
pub fn test_into_result() {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
assert_eq!(ok.into_result(), Ok(100));
assert_eq!(err.into_result(), Err(404));
}
#[test]
pub fn test_as_result() {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
let x = 100;
assert_eq!(ok.as_result(), Ok(&x));
let x = 404;
assert_eq!(err.as_result(), Err(&x));
}
}