std: Add ToOption/IntoOption/AsOption

This commit is contained in:
Erick Tryzelaar 2013-09-11 09:26:59 -07:00
parent b8a284e873
commit ff34740a29
3 changed files with 185 additions and 0 deletions

View File

@ -13,6 +13,7 @@
#[allow(missing_doc)];
use option::{Some, None};
use option;
use clone::Clone;
use container::Container;
use cmp::Eq;
@ -116,6 +117,36 @@ impl<L, R> Either<L, R> {
}
}
impl<L, R: Clone> option::ToOption<R> for Either<L, R> {
#[inline]
fn to_option(&self)-> option::Option<R> {
match *self {
Left(_) => None,
Right(ref r) => Some(r.clone()),
}
}
}
impl<L, R> option::IntoOption<R> for Either<L, R> {
#[inline]
fn into_option(self)-> option::Option<R> {
match self {
Left(_) => None,
Right(r) => Some(r),
}
}
}
impl<L, R> option::AsOption<R> for Either<L, R> {
#[inline]
fn as_option<'a>(&'a self) -> option::Option<&'a R> {
match *self {
Left(_) => None,
Right(ref r) => Some(r),
}
}
}
/// An iterator yielding the `Left` values of its source
pub type Lefts<L, R, Iter> = FilterMap<'static, Either<L, R>, L, Iter>;
@ -167,6 +198,9 @@ pub fn partition<L, R>(eithers: ~[Either<L, R>]) -> (~[L], ~[R]) {
mod tests {
use super::*;
use option::{IntoOption, ToOption, AsOption};
use option;
#[test]
fn test_either_left() {
let val = Left(10);
@ -260,4 +294,30 @@ mod tests {
assert_eq!(rights.len(), 0u);
}
#[test]
pub fn test_to_option() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
assert_eq!(right.to_option(), option::Some(100));
assert_eq!(left.to_option(), option::None);
}
#[test]
pub fn test_into_option() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
assert_eq!(right.into_option(), option::Some(100));
assert_eq!(left.into_option(), option::None);
}
#[test]
pub fn test_as_option() {
let right: Either<int, int> = Right(100);
let left: Either<int, int> = Left(404);
assert_eq!(right.as_option().unwrap(), &100);
assert_eq!(left.as_option(), option::None);
}
}

View File

@ -388,6 +388,44 @@ impl<T> Option<T> {
}
}
/// A generic trait for converting a value to a `Option`
pub trait ToOption<T> {
/// Convert to the `option` type
fn to_option(&self) -> Option<T>;
}
/// A generic trait for converting a value to a `Option`
pub trait IntoOption<T> {
/// Convert to the `option` type
fn into_option(self) -> Option<T>;
}
/// A generic trait for converting a value to a `Option`
pub trait AsOption<T> {
/// Convert to the `option` type
fn as_option<'a>(&'a self) -> Option<&'a T>;
}
impl<T: Clone> ToOption<T> for Option<T> {
#[inline]
fn to_option(&self) -> Option<T> { self.clone() }
}
impl<T> IntoOption<T> for Option<T> {
#[inline]
fn into_option(self) -> Option<T> { self }
}
impl<T> AsOption<T> for Option<T> {
#[inline]
fn as_option<'a>(&'a self) -> Option<&'a T> {
match *self {
Some(ref x) => Some(x),
None => None,
}
}
}
impl<T: Default> Option<T> {
/// Returns the contained value or default (for this type)
#[inline]
@ -711,4 +749,31 @@ mod tests {
assert!(!x.mutate_default(0i, |i| i+1));
assert_eq!(x, Some(0i));
}
#[test]
pub fn test_to_option() {
let some: Option<int> = Some(100);
let none: Option<int> = None;
assert_eq!(some.to_option(), Some(100));
assert_eq!(none.to_option(), None);
}
#[test]
pub fn test_into_option() {
let some: Option<int> = Some(100);
let none: Option<int> = None;
assert_eq!(some.into_option(), Some(100));
assert_eq!(none.into_option(), None);
}
#[test]
pub fn test_as_option() {
let some: Option<int> = Some(100);
let none: Option<int> = None;
assert_eq!(some.as_option().unwrap(), &100);
assert_eq!(none.as_option(), None);
}
}

View File

@ -17,6 +17,7 @@ use cmp::Eq;
use either;
use iter::Iterator;
use option::{None, Option, Some, OptionIterator};
use option;
use vec;
use vec::OwnedVector;
use to_str::ToStr;
@ -255,6 +256,36 @@ impl<T, E: Clone + ToStr> Result<T, E> {
}
}
impl<T: Clone, E> option::ToOption<T> for Result<T, E> {
#[inline]
fn to_option(&self)-> Option<T> {
match *self {
Ok(ref t) => Some(t.clone()),
Err(_) => None,
}
}
}
impl<T, E> option::IntoOption<T> for Result<T, E> {
#[inline]
fn into_option(self)-> Option<T> {
match self {
Ok(t) => Some(t),
Err(_) => None,
}
}
}
impl<T, E> option::AsOption<T> for Result<T, E> {
#[inline]
fn as_option<'a>(&'a self)-> Option<&'a T> {
match *self {
Ok(ref t) => Some(t),
Err(_) => None,
}
}
}
#[inline]
#[allow(missing_doc)]
pub fn map_opt<T, U: ToStr, V>(o_t: &Option<T>,
@ -336,6 +367,8 @@ mod tests {
use either;
use iter::range;
use option::{IntoOption, ToOption, AsOption};
use option;
use str::OwnedStr;
use vec::ImmutableVector;
@ -460,4 +493,31 @@ mod tests {
.map(|f| (*f)())),
Err(1));
}
#[test]
pub fn test_to_option() {
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);
}
#[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);
}
#[test]
pub fn test_as_option() {
let ok: Result<int, int> = Ok(100);
let err: Result<int, int> = Err(404);
assert_eq!(ok.as_option().unwrap(), &100);
assert_eq!(err.as_option(), option::None);
}
}