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

argonaut.DecodeResult.scala Maven / Gradle / Ivy

The newest version!
package argonaut

case class DecodeResult[A](result: Either[(String, CursorHistory), A]) {
  def fold[X](
    failure: (String, CursorHistory) => X,
    value: A => X
  ): X = result.fold({case (m, h) => failure(m, h)}, value)

  final def loop[X, B](e: (String, CursorHistory) => X, f: B => Either[X, DecodeResult[B]])(implicit ev: A <:< B): X =
    DecodeResult.loop(this.map(ev), e, f)

  def isError: Boolean =
    result.isLeft

  def map[B](f: A => B): DecodeResult[B] =
    DecodeResult(result.map(f))

  def flatMap[B](f: A => DecodeResult[B]): DecodeResult[B] =
    DecodeResult(result.flatMap(f(_).result))

  def message: Option[String] =
    failure.map(_._1)

  def history: Option[CursorHistory] =
    failure.map(_._2)

  def toOption: Option[A] =
    result.toOption

  def toEither: Either[(String, CursorHistory), A] =
    result

  def getOr[AA >: A](els: => AA): AA =
    toOption.getOrElse(els)

  /** alias for `toOption` */
  def value: Option[A] =
    result.toOption

  def failure: Option[(String, CursorHistory)] =
    result.left.toOption

  def option: DecodeResult[Option[A]] =
    result match {
      case Left((s, h)) => DecodeResult.fail(s, h)
      case Right(a) => DecodeResult.ok(Some(a))
    }

  def |||[AA >: A](r: => DecodeResult[AA]): DecodeResult[AA] =
    DecodeResult(result.fold(_ => r.result, _ => result))

  override def toString(): String = s"DecodeResult(${result})"
}

object DecodeResult extends DecodeResults {
  def ok[A](value: A): DecodeResult[A] =
    DecodeResult(Right(value))

  def fail[A](s: String, h: CursorHistory): DecodeResult[A] =
    DecodeResult(Left((s, h)))
}

trait DecodeResults {
  type DecodeEither[A] = Either[(String, CursorHistory), A]

  def okResult[A](value: A): DecodeResult[A] =
    DecodeResult.ok(value)

  def failResult[A](s: String, h: CursorHistory): DecodeResult[A] =
    DecodeResult.fail(s, h)

  @annotation.tailrec
  final def loop[A, X](d: DecodeResult[A], e: (String, CursorHistory) => X, f: A => Either[X, DecodeResult[A]]): X = {
    if (d.isError) {
      e(d.message.get, d.history.get)
    } else {
      f(d.value.get) match {
        case Left(x) => x
        case Right(a) => loop(a, e, f)
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy