trait FutureSugar extends AnyRef
Trait providing an implicit class that adds a validating method to
Future, which takes one or more validation functions and returns either the
same Future if either the Future had already failed or its value
passes all the functions, or ValidationFailedException containing an error message
describing the first validation that failed.
Here's an example validation method, which passes if the given Int is evenly
divisible by 10 (i.e., the result will be Pass). If the value does not pass
this test, the result is a Fail containing a helpful error message string.
scala> import org.scalactic._
import org.scalactic._
scala> import FutureSugar._
import org.scalactic.FutureSugar._
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> def isRound(i: Int): Validation[ErrorMessage] =
| if (i % 10 == 0) Pass else Fail(i + " was not a round number")
isRound: (i: Int)org.scalactic.Validation[org.scalactic.ErrorMessage]
Validation will be attempted on a successful Try. If the validation succeeds, the
resulting Future will be the same successful Future with the same value. (A
"validation" only transforms the Future if the validation fails, otherwise it is the
same Future. The only difference is its value has now been proven valid.)
In the following example, a successful Future[Int] with the value 100
passes the validation (which checks whether 100 is evenly divisible by 10), therefore
the result of the validating call is the same successful Future
with the same value.
scala> val fut100 = Future(100) fut100: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@67f9c9c6 scala> fut100.value res0: Option[scala.util.Try[Int]] = Some(Success(100)) scala> val round100 = fut100.validating(isRound) round100: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@1ac2f0d1 scala> round100.value res1: Option[scala.util.Try[Int]] = Some(Success(100))
If validation fails, the successful Future will be transformed into a failed one, with
a ValidationFailedException that contains the error message
returned by the validation function. In the following example, 42 fails the validation because it
is not evenly divisible by 10:
scala> val fut42 = Future(42) fut42: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@19c6e4d1 scala> fut42.value res2: Option[scala.util.Try[Int]] = Some(Success(42)) scala> val round42 = fut42.validating(isRound) round42: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@b5175d scala> round42.value res3: Option[scala.util.Try[Int]] = Some(Failure(org.scalactic.exceptions.ValidationFailedException: 42 was not a round number))
If validating is called on a failed Future, it just returns the same failed Future:
scala> val futEx = Future[Int] { throw new Exception("oops!") }
futEx: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@3ba0299c
scala> futEx.value
res4: Option[scala.util.Try[Int]] = Some(Failure(java.lang.Exception: oops!))
scala> val roundEx = futEx.validating(isRound)
roundEx: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@22bf1acf
scala> roundEx.value
res5: Option[scala.util.Try[Int]] = Some(Failure(java.lang.Exception: oops!))
The validating method accepts one or more validation functions. If you
pass more than one, they will be tried in order up until the first failure, whose
error message will appear in the ValidationFailedException. In other words,
validating will short circuit at the first error and return that. It
will not accumulate errors. For example, the following validation will short circuit
after the isDivBy3 function fails:
scala> def isDivBy3(i: Int): Validation[ErrorMessage] =
| if (i % 3 == 0) Pass else Fail(i + " was not divisible by 3")
isDivBy3: (i: Int)org.scalactic.Validation[org.scalactic.ErrorMessage]
scala> def isAnswerToLifeTheUniverseAndEverything(i: Int): Validation[ErrorMessage] =
| if (i == 42) Pass else Fail(i + " did not equal 42")
isAnswerToLifeTheUniverseAndEverything: (i: Int)org.scalactic.Validation[org.scalactic.ErrorMessage]
scala> val futShort = fut100.validating(isRound, isDivBy3, isAnswerToLifeTheUniverseAndEverything)
futShort: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@30bb943e
scala> futShort.value
res11: Option[scala.util.Try[Int]] = Some(Failure(org.scalactic.exceptions.ValidationFailedException: 100 was not divisible by 3))
- Source
- FutureSugar.scala
- Alphabetic
- By Inheritance
- FutureSugar
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Type Members
- implicit class Futureizer[T] extends AnyRef
Implicit class that adds a
validationmethod toFuture, which takes one or more functions that validate theFuture's value.Implicit class that adds a
validationmethod toFuture, which takes one or more functions that validate theFuture's value.See the main documentation for trait
FutureSugarfor more detail and examples.
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()