Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2009-2018 Lightbend Inc.
*/
package play.api.libs.json
/**
* The result for a successful parsing.
*/
case class JsSuccess[T](value: T, path: JsPath = JsPath()) extends JsResult[T] {
def get: T = value
val isSuccess = true
val isError = false
def fold[U](invalid: Seq[(JsPath, Seq[JsonValidationError])] => U, valid: T => U): U = valid(value)
def map[U](f: T => U): JsResult[U] = copy(value = f(value))
def flatMap[U](f: T => JsResult[U]): JsResult[U] = f(value).repath(path)
def foreach(f: T => Unit): Unit = f(value)
def repath(path: JsPath): JsResult[T] = JsSuccess(value, path ++ this.path)
def getOrElse[U >: T](t: => U): U = value
def orElse[U >: T](t: => JsResult[U]): JsResult[U] = this
def asOpt: Option[T] = Some(value)
def asEither: Either[Seq[(JsPath, Seq[JsonValidationError])], T] = Right(value)
def recover[U >: T](errManager: PartialFunction[JsError, U]): JsResult[U] = this
def recoverTotal[U >: T](errManager: JsError => U): U = value
}
/**
* The result in case of parsing `errors`.
*/
case class JsError(errors: Seq[(JsPath, Seq[JsonValidationError])]) extends JsResult[Nothing] {
def get: Nothing = throw new NoSuchElementException("JsError.get")
def ++(error: JsError): JsError = JsError.merge(this, error)
def :+(error: (JsPath, JsonValidationError)): JsError = JsError.merge(this, JsError(error))
def append(error: (JsPath, JsonValidationError)): JsError = this.:+(error)
def +:(error: (JsPath, JsonValidationError)): JsError = JsError.merge(JsError(error), this)
def prepend(error: (JsPath, JsonValidationError)): JsError = this.+:(error)
val isSuccess = false
val isError = true
def fold[U](invalid: Seq[(JsPath, Seq[JsonValidationError])] => U, valid: Nothing => U): U = invalid(errors)
def map[U](f: Nothing => U): JsResult[U] = this
def flatMap[U](f: Nothing => JsResult[U]): JsResult[U] = this
def foreach(f: Nothing => Unit): Unit = ()
def repath(path: JsPath): JsResult[Nothing] =
JsError(errors.map { case (p, s) => path ++ p -> s })
def getOrElse[U >: Nothing](t: => U): U = t
def orElse[U >: Nothing](t: => JsResult[U]): JsResult[U] = t
val asOpt = None
def asEither: Either[Seq[(JsPath, Seq[JsonValidationError])], Nothing] = Left(errors)
def recover[U >: Nothing](errManager: PartialFunction[JsError, U]): JsResult[U] = JsSuccess(errManager(this))
def recoverTotal[U >: Nothing](errManager: JsError => U): U = errManager(this)
}
object JsError {
def apply(): JsError = JsError(Seq(JsPath -> Seq()))
def apply(error: JsonValidationError): JsError = JsError(Seq(JsPath -> Seq(error)))
def apply(error: String): JsError = JsError(JsonValidationError(error))
def apply(error: (JsPath, JsonValidationError)): JsError = JsError(Seq(error._1 -> Seq(error._2)))
def apply(path: JsPath, error: JsonValidationError): JsError = JsError(path -> error)
def apply(path: JsPath, error: String): JsError = JsError(path -> JsonValidationError(error))
def merge(e1: Seq[(JsPath, Seq[JsonValidationError])], e2: Seq[(JsPath, Seq[JsonValidationError])]): Seq[(JsPath, Seq[JsonValidationError])] = {
(e1 ++ e2).groupBy(_._1).mapValues(_.flatMap(_._2)).toList
}
def merge(e1: JsError, e2: JsError): JsError = {
JsError(merge(e1.errors, e2.errors))
}
def toJson(e: JsError): JsObject = toJson(e.errors, false)
def toJson(errors: Seq[(JsPath, Seq[JsonValidationError])]): JsObject = toJson(errors, false)
//def toJsonErrorsOnly: JsValue = original // TODO
def toFlatForm(e: JsError): Seq[(String, Seq[JsonValidationError])] = e.errors.map { case (path, seq) => path.toJsonString -> seq }
private def toJson(errors: Seq[(JsPath, Seq[JsonValidationError])], flat: Boolean): JsObject = {
errors.foldLeft(JsObject.empty) { (obj, error) =>
obj ++ JsObject(Seq(error._1.toJsonString -> error._2.foldLeft(JsArray.empty) { (arr, err) =>
val msg = JsArray({
if (flat) Array(JsString(err.message))
else err.messages.map(JsString(_)).toArray[JsValue]
})
arr :+ JsObject(Seq(
"msg" -> msg,
"args" -> JsArray(err.args.map(toJson).toArray[JsValue])
))
}))
}
}
/**
* Serializer for Any, used for the args of errors.
*/
private def toJson(a: Any): JsValue = a match {
case s: String => JsString(s)
case nb: Int => JsNumber(nb)
case nb: Short => JsNumber(nb)
case nb: Long => JsNumber(nb)
case nb: Double => JsNumber(nb)
case nb: Float => JsNumber(nb)
case b: Boolean => JsBoolean(b)
case js: JsValue => js
case x => JsString(x.toString)
}
}
sealed trait JsResult[+A] { self =>
def isSuccess: Boolean
def isError: Boolean
/**
* Either applies the `invalid` function if this result is an error,
* or applies the `valid` function on the successful value.
*/
def fold[B](invalid: Seq[(JsPath, Seq[JsonValidationError])] => B, valid: A => B): B
/**
* If this result is successful, applies the function `f` on the parsed value.
*/
def map[B](f: A => B): JsResult[B]
/**
* If this result is successful, applies the function `f` on the parsed value.
*/
def flatMap[B](f: A => JsResult[B]): JsResult[B]
/**
* If this result is successful, applies the function `f` on the parsed value.
*/
def foreach(f: A => Unit): Unit
def filterNot(error: JsError)(p: A => Boolean): JsResult[A] =
flatMap { a => if (p(a)) error else JsSuccess(a) }
def filterNot(p: A => Boolean): JsResult[A] =
flatMap { a => if (p(a)) JsError() else JsSuccess(a) }
def filter(p: A => Boolean): JsResult[A] =
flatMap { a => if (p(a)) JsSuccess(a) else JsError() }
def filter(otherwise: JsError)(p: A => Boolean): JsResult[A] =
flatMap { a => if (p(a)) JsSuccess(a) else otherwise }
def collect[B](otherwise: JsonValidationError)(p: PartialFunction[A, B]): JsResult[B] = flatMap {
case t if p.isDefinedAt(t) => JsSuccess(p(t))
case _ => JsError(otherwise)
}
def withFilter(p: A => Boolean) = new WithFilter(p)
final class WithFilter(p: A => Boolean) {
def map[B](f: A => B): JsResult[B] = self match {
case JsSuccess(a, path) =>
if (p(a)) JsSuccess(f(a), path)
else JsError()
case e @ JsError(_) => e
}
def flatMap[B](f: A => JsResult[B]): JsResult[B] = self match {
case JsSuccess(a, path) =>
if (p(a)) f(a).repath(path)
else JsError()
case e @ JsError(_) => e
}
def foreach(f: A => Unit): Unit = self match {
case JsSuccess(a, _) if p(a) => f(a)
case _ => ()
}
def withFilter(q: A => Boolean) = new WithFilter(a => p(a) && q(a))
}
/** Updates the JSON path */
def repath(path: JsPath): JsResult[A]
/** Not recommended */
def get: A
/** Either returns the successful value, or the value from `t`. */
def getOrElse[AA >: A](t: => AA): AA
/**
* Either returns this result if successful, or the result from `t`.
*/
def orElse[AA >: A](t: => JsResult[AA]): JsResult[AA]
/**
* Transforms this result either `Some` option with the successful value,
* or as `None` in case of JSON error.
*/
def asOpt: Option[A]
/**
* Returns either the result errors (at `Left`),
* or the successful value (at `Right`).
*/
def asEither: Either[Seq[(JsPath, Seq[JsonValidationError])], A]
/**
* If this result is not successful,
* recovers the errors with the given function.
*/
def recover[AA >: A](errManager: PartialFunction[JsError, AA]): JsResult[AA]
/**
* If this result is not successful,
* recovers the errors with the given function.
*/
def recoverTotal[AA >: A](errManager: JsError => AA): AA
}
object JsResult {
import scala.util.{ Failure, Try, Success }
import play.api.libs.functional._
case class Exception(cause: JsError)
extends java.lang.Exception(Json stringify JsError.toJson(cause))
with scala.util.control.NoStackTrace
/**
* Returns a JSON validation as a [[scala.util.Try]].
*
* @tparam T the type for the parsing
* @param result the JSON validation result
* @param err the function to be applied if the results is an error
*
* {{{
* import scala.concurrent.Future
* import play.api.libs.json.JsResult
*
* def toFuture[T](res: JsResult[T]): Future[T] =
* Future.fromTry(JsResult.toTry(res))
* }}}
*/
def toTry[T](result: JsResult[T], err: JsError => Throwable = Exception(_)): Try[T] = result match {
case e @ JsError(_) => Failure(err(e))
case s @ JsSuccess(v, _) => Success(v)
}
implicit def alternativeJsResult(implicit a: Applicative[JsResult]): Alternative[JsResult] = new Alternative[JsResult] {
val app = a
def |[A, B >: A](alt1: JsResult[A], alt2: JsResult[B]): JsResult[B] = (alt1, alt2) match {
case (JsError(e), JsSuccess(t, p)) => JsSuccess(t, p)
case (JsSuccess(t, p), _) => JsSuccess(t, p)
case (JsError(e1), JsError(e2)) => JsError(JsError.merge(e1, e2))
}
def empty: JsResult[Nothing] = JsError(Seq.empty)
}
implicit val applicativeJsResult: Applicative[JsResult] = new Applicative[JsResult] {
def pure[A](a: A): JsResult[A] = JsSuccess(a)
def map[A, B](m: JsResult[A], f: A => B): JsResult[B] = m.map(f)
def apply[A, B](mf: JsResult[A => B], ma: JsResult[A]): JsResult[B] = (mf, ma) match {
case (JsSuccess(f, _), JsSuccess(a, _)) => JsSuccess(f(a))
case (JsError(e1), JsError(e2)) => JsError(JsError.merge(e1, e2))
case (JsError(e), _) => JsError(e)
case (_, JsError(e)) => JsError(e)
}
}
implicit val functorJsResult: Functor[JsResult] = new Functor[JsResult] {
override def fmap[A, B](m: JsResult[A], f: A => B) = m map f
}
}