An alternative to a for-comprehension, is the following class which implicitely adds an unpack
method to a JValue
:
case class UnpackableJValue(jv: JValue) {
import scala.util.Try
def unpack[A](f: JValue => A): A = f(jv)
def unpackList[A](f: JValue => A): List[A] = jv match {
case JArray(values) => values map f
case _ => List.empty
}
def unpackOpt[A](f: JValue => A): Option[A] = Try(f(jv)).toOption
}
object UnpackableJValue {
implicit def jvalue2unpackable(jv: JValue) = UnpackableJValue(jv)
}
The unpack
method receives a function which is responsible to create a domain value from a JValue
.
import UnpackableJValue._
implicit val formats = DefaultFormats
case class Status(success: Boolean, code: Int, message: String)
val json = parse(
"""
|{
| "success": true,
| "statusCode": 0,
| "statusMessage": "Ok",
| "payload": { }
|}
""".stripMargin)
val res = json.unpack[Status] { v =>
val success = (v \ "success").extract[Boolean]
val code = (v \ "statusCode").extract[Int]
val message = (v \ "statusMessage").extract[String]
Status(success, code, message)
}
println(res)
// Status(true,0,Ok)