Dyin
Dyin

Reputation: 5366

Scala JSON4S to return a triple during field deserialization

I'm working with JSON4S and it handles missing fields correctly, when the corresponding object's field is an option. I'm using

implicit val formats =
  Serialization.formats(NoTypeHints) +
    new org.json4s.ext.EnumNameSerializer(E)

and read[T](json).

It's perfect, except one thing. I'd like to designate between missing and null fields. What I'd like to have for each field of my T is to have something like a Triple instead of Option, where this triple would be either a Some(t), Missing or Nullified in analogue to how Option works. I have no problem in defining such a structure, but unfortunatelly I'm not so familiar with how JSON4S works, or how could I (maybe) "intercept" the parsing of a field to achieve such a value-extraction.

As an alternative, it also would be great if the parser would set the corresponding field of T to null if the field is field: null instead of setting it to None. This would not feel Scalaish I think.

Upvotes: 0

Views: 197

Answers (1)

nmat
nmat

Reputation: 7591

You should probably implement a custom serializer for T. I would use the following format because it allows for more flexibility and order independent input:

import org.json4s.CustomSerializer
import org.json4s.JsonAST._
import org.json4s.JsonDSL._

case class Animal(name: String, nrLegs: Int)

class AnimalSerializer extends CustomSerializer[Animal](format => ( {
  case jsonObj: JObject =>
    val name = (jsonObj \ "name") //JString
    val nrLegs = (jsonObj \ "nrLegs") //JInt

    Animal(name.extract[String], nrLegs.extract[Int])
}, {
  case animal: Animal =>
    ("name" -> animal.name) ~
      ("nrLegs" -> animal.nrLegs)
}
))

To handle null/empty values take a look at the JSValue trait. For null values you should match with JNull and for non present values with JNothing.

Upvotes: 1

Related Questions