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])
}
}
}
}
}