All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.coursier.util.ValidationNel.scala Maven / Gradle / Ivy

There is a newer version: 2.1.19
Show newest version
package coursier.util

// not covariant because scala.:: isn't (and is there a point in being covariant in R but not L?)
final case class ValidationNel[L, R](either: Either[::[L], R]) {
  def isSuccess: Boolean =
    either.isRight
  def map[S](f: R => S): ValidationNel[L, S] =
    ValidationNel(either.map(f))
  def flatMap[S](f: R => ValidationNel[L, S]): ValidationNel[L, S] =
    ValidationNel(either.flatMap(r => f(r).either))

  def zip[R1](other: ValidationNel[L, R1]): ValidationNel[L, (R, R1)] =
    (either, other.either) match {
      case (Right(ra), Right(rb)) =>
        ValidationNel.success((ra, rb))
      case _ =>
        val errs = either.left.getOrElse(Nil) ::: other.either.left.getOrElse(Nil)
        errs match {
          case h :: t =>
            ValidationNel.failures(h, t: _*)
          case Nil =>
            sys.error("Can't possibly happen")
        }
    }

  def zip[R1, R2](
    second: ValidationNel[L, R1],
    third: ValidationNel[L, R2]
  ): ValidationNel[L, (R, R1, R2)] =
    (either, second.either, third.either) match {
      case (Right(ra), Right(rb), Right(rc)) =>
        ValidationNel.success((ra, rb, rc))
      case _ =>
        val errs = either.left.getOrElse(Nil) :::
          second.either.left.getOrElse(Nil) :::
          third.either.left.getOrElse(Nil)
        errs match {
          case h :: t =>
            ValidationNel.failures(h, t: _*)
          case Nil =>
            sys.error("Can't possibly happen")
        }
    }
}

object ValidationNel {
  def fromEither[L, R](either: Either[L, R]): ValidationNel[L, R] =
    ValidationNel(either.left.map(l => ::(l, Nil)))
  def success[L]: SuccessBuilder[L] =
    new SuccessBuilder
  def failure[R]: FailureBuilder[R] =
    new FailureBuilder
  def failures[R]: FailuresBuilder[R] =
    new FailuresBuilder

  final class SuccessBuilder[L] {
    def apply[R](r: R): ValidationNel[L, R] =
      ValidationNel(Right(r))
  }
  final class FailureBuilder[R] {
    def apply[L](l: L): ValidationNel[L, R] =
      ValidationNel(Left(::(l, Nil)))
  }
  final class FailuresBuilder[R] {
    def apply[L](l: L, rest: L*): ValidationNel[L, R] =
      ValidationNel(Left(::(l, rest.toList)))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy