std: add result.map_move, result.map_err_move

This commit is contained in:
Erick Tryzelaar 2013-08-04 16:05:25 -07:00
parent 5c08237456
commit 9218aaa00e
6 changed files with 66 additions and 20 deletions

View File

@ -2028,7 +2028,7 @@ fn check(n: int, ans: &str) {
#[test]
fn test_from_str_radix() {
fn check(s: &str, ans: Option<int>) {
let ans = ans.map(|&n| IntConvertible::from_int::<BigInt>(n));
let ans = ans.map_move(|n| IntConvertible::from_int::<BigInt>(n));
assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
}
check("10", Some(10));

View File

@ -4443,15 +4443,15 @@ pub fn count_traits_and_supertraits(tcx: ctxt,
}
pub fn get_tydesc_ty(tcx: ctxt) -> Result<t, ~str> {
do tcx.lang_items.require(TyDescStructLangItem).map |tydesc_lang_item| {
tcx.intrinsic_defs.find_copy(tydesc_lang_item)
do tcx.lang_items.require(TyDescStructLangItem).map_move |tydesc_lang_item| {
tcx.intrinsic_defs.find_copy(&tydesc_lang_item)
.expect("Failed to resolve TyDesc")
}
}
pub fn get_opaque_ty(tcx: ctxt) -> Result<t, ~str> {
do tcx.lang_items.require(OpaqueStructLangItem).map |opaque_lang_item| {
tcx.intrinsic_defs.find_copy(opaque_lang_item)
do tcx.lang_items.require(OpaqueStructLangItem).map_move |opaque_lang_item| {
tcx.intrinsic_defs.find_copy(&opaque_lang_item)
.expect("Failed to resolve Opaque")
}
}

View File

@ -131,9 +131,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
// ty is the value supplied for the type parameter A...
let mut param_result = ~[];
do ty::each_bound_trait_and_supertraits(
tcx, type_param_bounds.trait_bounds) |trait_ref|
{
do ty::each_bound_trait_and_supertraits(tcx, type_param_bounds.trait_bounds) |trait_ref| {
// ...and here trait_ref is each bound that was declared on A,
// expressed in terms of the type parameters.

View File

@ -110,16 +110,16 @@ fn test_tls_multitask() {
set(my_key, @~"parent data");
do task::spawn {
// TLS shouldn't carry over.
assert!(get(my_key, |k| k.map(|&k| *k)).is_none());
assert!(get(my_key, |k| k.map_move(|k| *k)).is_none());
set(my_key, @~"child data");
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) ==
assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) ==
~"child data");
// should be cleaned up for us
}
// Must work multiple times
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
}
#[test]
@ -127,7 +127,7 @@ fn test_tls_overwrite() {
static my_key: Key<@~str> = &Key;
set(my_key, @~"first data");
set(my_key, @~"next data"); // Shouldn't leak.
assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"next data");
assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"next data");
}
#[test]

View File

@ -149,6 +149,40 @@ pub fn expect_err(self, reason: &str) -> E {
}
}
/// Call a method based on a previous result
///
/// If `self` is `Ok` then the value is extracted and passed to `op`
/// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
/// `Err` then it is immediately returned. This function can be used to
/// compose the results of two functions.
///
/// Example:
///
/// let res = do read_file(file).map_move |buf| {
/// parse_bytes(buf)
/// }
#[inline]
pub fn map_move<U>(self, op: &fn(T) -> U) -> Result<U,E> {
match self {
Ok(t) => Ok(op(t)),
Err(e) => Err(e)
}
}
/// Call a method based on a previous result
///
/// If `self` is `Err` then the value is extracted and passed to `op`
/// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
/// `Ok` then it is immediately returned. This function can be used to pass
/// through a successful result while handling an error.
#[inline]
pub fn map_err_move<F>(self, op: &fn(E) -> F) -> Result<T,F> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(op(e))
}
}
/// Call a method based on a previous result
///
/// If `self` is `Ok` then the value is extracted and passed to `op`
@ -312,7 +346,9 @@ pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
#[cfg(test)]
mod tests {
use super::*;
use either;
use str::OwnedStr;
pub fn op1() -> Result<int, ~str> { Ok(666) }
@ -359,14 +395,26 @@ pub fn test_impl_iter_err() {
#[test]
pub fn test_impl_map() {
assert_eq!(Ok::<~str, ~str>(~"a").map(|_x| ~"b"), Ok(~"b"));
assert_eq!(Err::<~str, ~str>(~"a").map(|_x| ~"b"), Err(~"a"));
assert_eq!(Ok::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Ok(~"ba"));
assert_eq!(Err::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Err(~"a"));
}
#[test]
pub fn test_impl_map_err() {
assert_eq!(Ok::<~str, ~str>(~"a").map_err(|_x| ~"b"), Ok(~"a"));
assert_eq!(Err::<~str, ~str>(~"a").map_err(|_x| ~"b"), Err(~"b"));
assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Ok(~"a"));
assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Err(~"ba"));
}
#[test]
pub fn test_impl_map_move() {
assert_eq!(Ok::<~str, ~str>(~"a").map_move(|x| x + ~"b"), Ok(~"ab"));
assert_eq!(Err::<~str, ~str>(~"a").map_move(|x| x + ~"b"), Err(~"a"));
}
#[test]
pub fn test_impl_map_err_move() {
assert_eq!(Ok::<~str, ~str>(~"a").map_err_move(|x| x + ~"b"), Ok(~"a"));
assert_eq!(Err::<~str, ~str>(~"a").map_err_move(|x| x + ~"b"), Err(~"ab"));
}
#[test]

View File

@ -465,10 +465,10 @@ fn tls() {
do run_in_newsched_task() {
static key: local_data::Key<@~str> = &local_data::Key;
local_data::set(key, @~"data");
assert!(*local_data::get(key, |k| k.map(|&k| *k)).unwrap() == ~"data");
assert!(*local_data::get(key, |k| k.map_move(|k| *k)).unwrap() == ~"data");
static key2: local_data::Key<@~str> = &local_data::Key;
local_data::set(key2, @~"data");
assert!(*local_data::get(key2, |k| k.map(|&k| *k)).unwrap() == ~"data");
assert!(*local_data::get(key2, |k| k.map_move(|k| *k)).unwrap() == ~"data");
}
}