Skip to content

Commit

Permalink
Cleaned up the option and result module in more detail
Browse files Browse the repository at this point in the history
Made both types implement more standard traits in a nicer way

Derived more traits
  • Loading branch information
Kimundi committed Nov 1, 2013
1 parent 0d92c53 commit c22e7f0
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 57 deletions.
66 changes: 30 additions & 36 deletions src/libstd/option.rs
Expand Up @@ -40,46 +40,28 @@
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,
/// Some value `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
/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -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),
}
}
}
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -814,17 +808,17 @@ 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]
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(()));
assert_eq!(some.into_result(), Ok(100));
assert_eq!(none.into_result(), Err(()));
}

#[test]
Expand Down
33 changes: 12 additions & 21 deletions src/libstd/result.rs
Expand Up @@ -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;
Expand All @@ -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),
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -588,17 +579,17 @@ 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]
pub fn test_into_option() {
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]
Expand All @@ -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]
Expand Down

0 comments on commit c22e7f0

Please sign in to comment.