You can transform an existing AST like this:
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
object test extends App {
val json = """[{
| "name": "Foo",
| "verified": {"email": true, "mobile": false}
|}, {
| "name": "Bar",
| "verified": {"email": false, "mobile": false}
|}]""".stripMargin
def t(js: JValue): JValue = for {
JString(name) <- js \ "name"
JBool(ver1) <- js \ "verified" \ "email"
JBool(ver2) <- js \ "verified" \ "mobile"
} yield ("name" -> name) ~ ("emailVerified" -> ver1) ~ ("mobileVerified" -> ver2)
for {
JArray(xs) <- parse(json)
} yield JArray(xs map t)
}
Another option is write a custom serializer for it:
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
object userTest extends App {
val json = """{
| "name": "Bar",
| "verified": {"email": false, "mobile": false}
|}""".stripMargin
case class UserFoo(name: String, emailVerified: Boolean, mobileVerified: Boolean)
class UserFooSerializer extends CustomSerializer[UserFoo](formats => ( {
case js: JValue =>
val u = for {
JString(name) <- js \ "name"
JBool(userVerified) <- js \ "verified" \ "email"
JBool(mobileVerified) <- js \ "verified" \ "mobile"
} yield UserFoo(name, userVerified, mobileVerified)
u.head
}, Map.empty))
implicit val formats = DefaultFormats + new UserFooSerializer
parse(json).extractOpt[UserFoo] map {
user =>
println(user)
// UserFoo(Bar,false,false)
println(pretty(Extraction.decompose(user)))
// {
// "name" : "Bar",
// "emailVerified" : false,
// "mobileVerified" : false
// }
}
}