From e45ed323c99cf105b807ca79c5561570ec5c93c8 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 26 May 2012 20:33:08 -0700 Subject: [PATCH] Add methods iter, iter_err, map, map_err to the result type. --- src/libcore/result.rs | 134 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index b0fad3192be..3c6622ba69d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -107,6 +107,79 @@ fn chain_err( } } +#[doc = " +Call a function based on a previous result + +If `res` is `ok` then the value is extracted and passed to `op` whereupon +`op`s result is returned. if `res` is `err` then it is immediately returned. +This function can be used to compose the results of two functions. + +Example: + + iter(read_file(file)) { |buf| + print_buf(buf) + } +"] +fn iter(res: result, f: fn(T)) { + alt res { + ok(t) { f(t) } + err(_) { } + } +} + +#[doc = " +Call a function based on a previous result + +If `res` is `err` then the value is extracted and passed to `op` whereupon +`op`s result is returned. if `res` is `ok` then it is immediately returned. +This function can be used to pass through a successful result while handling +an error. +"] +fn iter_err(res: result, f: fn(E)) { + alt res { + ok(_) { } + err(e) { f(e) } + } +} + +#[doc = " +Call a function based on a previous result + +If `res` is `ok` then the value is extracted and passed to `op` whereupon +`op`s result is wrapped in `ok` and returned. if `res` is `err` then it is +immediately returned. This function can be used to compose the results of two +functions. + +Example: + + let res = map(read_file(file)) { |buf| + parse_buf(buf) + } +"] +fn map(res: result, op: fn(T) -> U) + -> result { + alt res { + ok(t) { ok(op(t)) } + err(e) { err(e) } + } +} + +#[doc = " +Call a function based on a previous result + +If `res` is `err` then the value is extracted and passed to `op` whereupon +`op`s result is wrapped in an `err` and returned. if `res` is `ok` then it is +immediately returned. This function can be used to pass through a successful +result while handling an error. +"] +fn map_err(res: result, op: fn(E) -> F) + -> result { + alt res { + ok(t) { ok(t) } + err(e) { err(op(e)) } + } +} + impl extensions for result { fn get() -> T { get(self) } @@ -123,6 +196,34 @@ impl extensions for result { fn chain_err(op: fn(E) -> result) -> result { chain_err(self, op) } + + fn iter(f: fn(T)) { + alt self { + ok(t) { f(t) } + err(_) { } + } + } + + fn iter_err(f: fn(E)) { + alt self { + ok(_) { } + err(e) { f(e) } + } + } + + fn map(op: fn(T) -> U) -> result { + alt self { + ok(t) { ok(op(t)) } + err(e) { err(e) } + } + } + + fn map_err(op: fn(E) -> F) -> result { + alt self { + ok(t) { ok(t) } + err(e) { err(op(e)) } + } + } } #[doc = " @@ -248,4 +349,37 @@ mod tests { fn chain_failure() { assert get_err(chain(op3(), op2)) == "sadface"; } + + #[test] + fn test_impl_iter() { + let mut valid = false; + ok::("a").iter { |_x| valid = true; }; + assert valid; + + err::("b").iter { |_x| valid = false; }; + assert valid; + } + + #[test] + fn test_impl_iter_err() { + let mut valid = true; + ok::("a").iter_err { |_x| valid = false; }; + assert valid; + + valid = false; + err::("b").iter_err { |_x| valid = true; }; + assert valid; + } + + #[test] + fn test_impl_map() { + assert ok::("a").map { |_x| "b" } == ok("b"); + assert err::("a").map { |_x| "b" } == err("a"); + } + + #[test] + fn test_impl_map_err() { + assert ok::("a").map_err { |_x| "b" } == ok("a"); + assert err::("a").map_err { |_x| "b" } == err("b"); + } }