about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-10-28 18:09:48 -0700
committerBrian Anderson <banderson@mozilla.com>2011-10-29 01:25:11 -0700
commit2b62a80202e2855d47f20d271842e0e9aec6d8e2 (patch)
treea37878693d9c0aa58bfa63a3eed957f4502811ba
parentc1092fb6d88efe51e42df3aae2a321cc669e12a0 (diff)
stdlib: Add result::chain for composing results
-rw-r--r--src/lib/result.rs39
-rw-r--r--src/test/stdtest/result.rs17
-rw-r--r--src/test/stdtest/stdtest.rc1
3 files changed, 49 insertions, 8 deletions
diff --git a/src/lib/result.rs b/src/lib/result.rs
index ba5ead5d4db..8b07138d8d0 100644
--- a/src/lib/result.rs
+++ b/src/lib/result.rs
@@ -19,11 +19,11 @@ tag t<T, U> {
     */
     ok(T);
     /*
-    Variant: error
+    Variant: err
 
     Contains the error value
     */
-    error(U);
+    err(U);
 }
 
 /* Section: Operations */
@@ -40,14 +40,14 @@ If the result is an error
 fn get<T, U>(res: t<T, U>) -> T {
     alt res {
       ok(t) { t }
-      error(_) {
+      err(_) {
         fail "get called on error result";
       }
     }
 }
 
 /*
-Function: get
+Function: get_err
 
 Get the value out of an error result
 
@@ -55,9 +55,9 @@ Failure:
 
 If the result is not an error
 */
-fn get_error<T, U>(res: t<T, U>) -> U {
+fn get_err<T, U>(res: t<T, U>) -> U {
     alt res {
-      error(u) { u }
+      err(u) { u }
       ok(_) {
         fail "get_error called on ok result";
       }
@@ -72,7 +72,7 @@ Returns true if the result is <ok>
 fn success<T, U>(res: t<T, U>) -> bool {
     alt res {
       ok(_) { true }
-      error(_) { false }
+      err(_) { false }
     }
 }
 
@@ -83,4 +83,27 @@ Returns true if the result is <error>
 */
 fn failure<T, U>(res: t<T, U>) -> bool {
     !success(res)
-}
\ No newline at end of file
+}
+
+/*
+Function: chain
+
+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:
+
+> let res = chain(read_file(file), { |buf]
+>   ok(parse_buf(buf))
+> })
+
+*/
+fn chain<T, U, V>(res: t<T, V>, op: block(T) -> t<U, V>) -> t<U, V> {
+    alt res {
+      ok(t) { op(t) }
+      err(e) { err(e) }
+    }
+}
diff --git a/src/test/stdtest/result.rs b/src/test/stdtest/result.rs
new file mode 100644
index 00000000000..9a7b390a523
--- /dev/null
+++ b/src/test/stdtest/result.rs
@@ -0,0 +1,17 @@
+import std::result;
+
+fn op1() -> result::t<int, str> { result::ok(666) }
+
+fn op2(&&i: int) -> result::t<uint, str> { result::ok(i as uint + 1u) }
+
+fn op3() -> result::t<int, str> { result::err("sadface") }
+
+#[test]
+fn chain_success() {
+    assert result::get(result::chain(op1(), op2)) == 667u;
+}
+
+#[test]
+fn chain_failure() {
+    assert result::get_err(result::chain(op3(), op2)) == "sadface";
+}
\ No newline at end of file
diff --git a/src/test/stdtest/stdtest.rc b/src/test/stdtest/stdtest.rc
index b2b7522c2e1..c47b85c65f8 100644
--- a/src/test/stdtest/stdtest.rc
+++ b/src/test/stdtest/stdtest.rc
@@ -31,6 +31,7 @@ mod test;
 mod uint;
 mod float;
 mod math;
+mod result;
 
 // Local Variables:
 // mode: rust