summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/util/Try.scala29
-rw-r--r--test/junit/scala/util/TryTest.scala35
2 files changed, 64 insertions, 0 deletions
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index 89db57a55e..b0cf122f2a 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -111,6 +111,35 @@ sealed abstract class Try[+T] {
*/
def filter(p: T => Boolean): Try[T]
+ /** Creates a non-strict filter, which eventually converts this to a `Failure`
+ * if the predicate is not satisfied.
+ *
+ * Note: unlike filter, withFilter does not create a new Try.
+ * Instead, it restricts the domain of subsequent
+ * `map`, `flatMap`, `foreach`, and `withFilter` operations.
+ *
+ * As Try is a one-element collection, this may be a bit overkill,
+ * but it's consistent with withFilter on Option and the other collections.
+ *
+ * @param p the predicate used to test elements.
+ * @return an object of class `WithFilter`, which supports
+ * `map`, `flatMap`, `foreach`, and `withFilter` operations.
+ * All these operations apply to those elements of this Try
+ * which satisfy the predicate `p`.
+ */
+ @inline final def withFilter(p: T => Boolean): WithFilter = new WithFilter(p)
+
+ /** We need a whole WithFilter class to honor the "doesn't create a new
+ * collection" contract even though it seems unlikely to matter much in a
+ * collection with max size 1.
+ */
+ class WithFilter(p: T => Boolean) {
+ def map[U](f: T => U): Try[U] = Try.this filter p map f
+ def flatMap[U](f: T => Try[U]): Try[U] = Try.this filter p flatMap f
+ def foreach[U](f: T => U): Unit = Try.this filter p foreach f
+ def withFilter(q: T => Boolean): WithFilter = new WithFilter(x => p(x) && q(x))
+ }
+
/**
* Applies the given function `f` if this is a `Failure`, otherwise returns this if this is a `Success`.
* This is like `flatMap` for the exception.
diff --git a/test/junit/scala/util/TryTest.scala b/test/junit/scala/util/TryTest.scala
new file mode 100644
index 0000000000..03604a8065
--- /dev/null
+++ b/test/junit/scala/util/TryTest.scala
@@ -0,0 +1,35 @@
+package scala.util
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import org.junit.Assert._
+
+/* Test Try's withFilter method, which was added along with the -Xfuture fix for SI-6455 */
+@RunWith(classOf[JUnit4])
+class TryTest {
+ @Test
+ def withFilterFail(): Unit = {
+ val fail = for (x <- util.Try(1) if x > 1) yield x
+ assert(fail.isFailure)
+ }
+
+ @Test
+ def withFilterSuccess(): Unit = {
+ val success1 = for (x <- util.Try(1) if x >= 1) yield x
+ assertEquals(success1, util.Success(1))
+ }
+
+ @Test
+ def withFilterFlatMap(): Unit = {
+ val successFlatMap = for (x <- util.Try(1) if x >= 1; y <- util.Try(2) if x < y) yield x
+ assertEquals(successFlatMap, util.Success(1))
+ }
+
+ @Test
+ def withFilterForeach(): Unit = {
+ var ok = false
+ for (x <- util.Try(1) if x == 1) ok = x == 1
+ assert(ok)
+ }
+} \ No newline at end of file