Cleaned up the option and result module in more detail

Made both types implement more standard traits in a nicer way

Derived more traits
This commit is contained in:
Marvin Löbel 2013-11-01 12:25:36 +01:00
parent 0d92c53f4a
commit c22e7f02d1
2 changed files with 42 additions and 57 deletions

View File

@ -40,21 +40,21 @@
use any::Any;
use clone::Clone;
use clone::DeepClone;
use cmp::{Eq,Ord};
use cmp::{Eq, TotalEq, TotalOrd};
use default::Default;
use either;
use fmt;
use iter::{Iterator, DoubleEndedIterator, ExactSize};
use iter;
use kinds::Send;
use num::Zero;
use result;
use str::{StrSlice, OwnedStr};
use result::{IntoResult, ToResult, AsResult};
use result::{Result, Ok, Err};
use str::OwnedStr;
use to_str::ToStr;
use util;
/// The option type
#[deriving(Clone, DeepClone, Eq, ToStr)]
#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
pub enum Option<T> {
/// No value
None,
@ -62,24 +62,6 @@ pub enum Option<T> {
Some(T)
}
impl<T: Eq + Ord> Ord for Option<T> {
fn lt(&self, other: &Option<T>) -> bool {
iter::order::lt(self.iter(), other.iter())
}
fn le(&self, other: &Option<T>) -> bool {
iter::order::le(self.iter(), other.iter())
}
fn ge(&self, other: &Option<T>) -> bool {
iter::order::ge(self.iter(), other.iter())
}
fn gt(&self, other: &Option<T>) -> bool {
iter::order::gt(self.iter(), other.iter())
}
}
/////////////////////////////////////////////////////////////////////////////
// Type implementation
/////////////////////////////////////////////////////////////////////////////
@ -436,22 +418,33 @@ impl<T> AsOption<T> for Option<T> {
// Trait implementations
/////////////////////////////////////////////////////////////////////////////
impl<T: Clone> result::ToResult<T, ()> for Option<T> {
impl<T: Clone> ToResult<T, ()> for Option<T> {
#[inline]
fn to_result(&self) -> result::Result<T, ()> {
fn to_result(&self) -> Result<T, ()> {
match *self {
Some(ref x) => result::Ok(x.clone()),
None => result::Err(()),
Some(ref x) => Ok(x.clone()),
None => Err(()),
}
}
}
impl<T> result::IntoResult<T, ()> for Option<T> {
impl<T> IntoResult<T, ()> for Option<T> {
#[inline]
fn into_result(self) -> result::Result<T, ()> {
fn into_result(self) -> Result<T, ()> {
match self {
Some(x) => result::Ok(x),
None => result::Err(()),
Some(x) => Ok(x),
None => Err(()),
}
}
}
impl<T> AsResult<T, ()> for Option<T> {
#[inline]
fn as_result<'a>(&'a self) -> Result<&'a T, &'a ()> {
static UNIT: () = ();
match *self {
Some(ref t) => Ok(t),
None => Err(&UNIT),
}
}
}
@ -536,7 +529,8 @@ mod tests {
use either::{IntoEither, ToEither};
use either;
use result::{IntoResult, ToResult};
use result;
use result::{Result, Ok, Err};
use str::StrSlice;
use util;
#[test]
@ -814,8 +808,8 @@ mod tests {
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(()));
assert_eq!(some.to_result(), Ok(100));
assert_eq!(none.to_result(), Err(()));
}
#[test]
@ -823,8 +817,8 @@ mod tests {
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(()));
assert_eq!(some.into_result(), Ok(100));
assert_eq!(none.into_result(), Err(()));
}
#[test]

View File

@ -18,7 +18,8 @@ use fmt;
use iter::Iterator;
use kinds::Send;
use option::{None, Option, Some, OptionIterator};
use option;
use option::{ToOption, IntoOption, AsOption};
use str::OwnedStr;
use to_str::ToStr;
use vec::OwnedVector;
use vec;
@ -28,7 +29,7 @@ use vec;
/// In order to provide informative error messages, `E` is required to implement `ToStr`.
/// It is further recommended for `E` to be a descriptive error type, eg a `enum` for
/// all possible errors cases.
#[deriving(Clone, Eq)]
#[deriving(Clone, DeepClone, Eq, Ord, TotalEq, TotalOrd, ToStr)]
pub enum Result<T, E> {
/// Contains the successful result value
Ok(T),
@ -300,7 +301,7 @@ impl<T, E> AsResult<T, E> for Result<T, E> {
// Trait implementations
/////////////////////////////////////////////////////////////////////////////
impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
impl<T: Clone, E> ToOption<T> for Result<T, E> {
#[inline]
fn to_option(&self) -> Option<T> {
match *self {
@ -310,7 +311,7 @@ impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
}
}
impl<T, E> option::IntoOption<T> for Result<T, E> {
impl<T, E> IntoOption<T> for Result<T, E> {
#[inline]
fn into_option(self) -> Option<T> {
match self {
@ -320,7 +321,7 @@ impl<T, E> option::IntoOption<T> for Result<T, E> {
}
}
impl<T, E> option::AsOption<T> for Result<T, E> {
impl<T, E> AsOption<T> for Result<T, E> {
#[inline]
fn as_option<'a>(&'a self) -> Option<&'a T> {
match *self {
@ -360,16 +361,6 @@ impl<T, E> either::AsEither<E, T> for Result<T, E> {
}
}
impl<T: ToStr, E: ToStr> ToStr for Result<T, E> {
#[inline]
fn to_str(&self) -> ~str {
match *self {
Ok(ref t) => format!("Ok({:s})", t.to_str()),
Err(ref e) => format!("Err({:s})", e.to_str())
}
}
}
impl<T: fmt::Default, E: fmt::Default> fmt::Default for Result<T, E> {
#[inline]
fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
@ -457,7 +448,7 @@ mod tests {
use either;
use iter::range;
use option::{IntoOption, ToOption, AsOption};
use option;
use option::{Option, Some, None};
use vec::ImmutableVector;
use to_str::ToStr;
@ -588,8 +579,8 @@ mod tests {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
assert_eq!(ok.to_option(), option::Some(100));
assert_eq!(err.to_option(), option::None);
assert_eq!(ok.to_option(), Some(100));
assert_eq!(err.to_option(), None);
}
#[test]
@ -597,8 +588,8 @@ mod tests {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
assert_eq!(ok.into_option(), option::Some(100));
assert_eq!(err.into_option(), option::None);
assert_eq!(ok.into_option(), Some(100));
assert_eq!(err.into_option(), None);
}
#[test]
@ -607,7 +598,7 @@ mod tests {
let err: Result<int, int> = Err(404);
assert_eq!(ok.as_option().unwrap(), &100);
assert_eq!(err.as_option(), option::None);
assert_eq!(err.as_option(), None);
}
#[test]