0
不知道是否有實現的功能鏈接上Any
如果遇到APIException
對象,將停止鏈更好的技術(不必延長Throwable
或Exception
,或使用throw
)。此外,寧願不使用scalaz
(讓我目瞪口呆)失敗快捷功能鏈接
- 鏈接功能應進行
APIException
進行到底,並將其返回。 - 鏈接功能不必攜帶中間結果結束時,除了從最後一個塊的輸出。
下面是測試規範:
class FailFastChainSpec extends PlaySpec {
import utils.Ops._
def fFailsValidation(): Option[APIException] = Some(UnknownException())
def fPassesValidation(): Option[APIException] = None
def someCalculation = "Results"
"Utils" when {
"FailFastChaining" must {
"return Left(APIException) when encountered (at beginning of chain)" in {
fFailsValidation |> {
someCalculation
} mustBe Left(UnknownException())
}
"return Right(...) when no APIExceptions are encountered" in {
fPassesValidation |> {
someCalculation
} mustBe Right(someCalculation)
}
"return Left(APIException) when encountered (in middle of chain with 1 link)" in {
fPassesValidation |> fFailsValidation mustBe Left(UnknownException())
}
"return Left(APIException) when encountered (at end of chain with 1 link)" in {
fPassesValidation |> {
Left(UnknownException())
} mustBe Left(UnknownException())
}
"return Left(APIException) when encountered (at end of chain with 2 links)" in {
fPassesValidation |> fPassesValidation |> {
Left(UnknownException())
} mustBe Left(UnknownException())
}
"return Right(...) when no APIExceptions are encountered (multiple links)" in {
fPassesValidation |> fPassesValidation |> fPassesValidation |> fPassesValidation |> {
Right(someCalculation)
} mustBe Right(someCalculation)
}
"return Right(...) when no APIExceptions are encountered (complex multiple links)" in {
fPassesValidation |> fPassesValidation |> {
Right("Cupcakes")
} |> fPassesValidation |> {
Right(someCalculation)
} mustBe Right(someCalculation)
}
}
}
}
這裏是我想出了,找這個改進的實現。
object Ops {
implicit def anyToAny[A](o: A): AnyOps[A] = new AnyOps[A](o)
class AnyOps[A](val a: A) {
def chain[B, C, D](c: C): Either[B, D] = |>[B,C,D](c)
def |>[B, C, D](c: C): Either[B, D] = {
a match {
case Some(v: APIException) => Left(v.asInstanceOf[B])
case v: APIException => Left(v.asInstanceOf[B])
case Left(v) => Left(v.asInstanceOf[B])
case _ => c match {
case Some(v: APIException) => Left(v.asInstanceOf[B])
case v: APIException => Left(v.asInstanceOf[B])
case Left(v) => Left(v.asInstanceOf[B])
case Right(v) => Right(v.asInstanceOf[D])
case v => Right(v.asInstanceOf[D])
}
}
}
}
}