Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json4s custom serializer with unordered fields

Tags:

scala

json4s

In the example given on the json4s readme https://github.com/json4s/json4s#serializing-non-supported-types the match only works if the fields are order {"start":0,"end":0}. If the start and end fields are swapped then the match doesn't work. Is there anyway to write the below case match such that the JSON field ordering doesn't matter?

case JObject(JField("start", JInt(s)) :: JField("end", JInt(e)) :: Nil)
like image 710
Benjamin Avatar asked Jul 24 '14 20:07

Benjamin


2 Answers

I haven't used this library, so I am not sure if this is the right approach: (I came up with this after spending a couple of minutes looking at the docs)

class IntervalSerializer extends CustomSerializer[Interval](format => (
  {
    case x: JObject =>
      x.obj.sortBy { case (k,_) => k } match {
        case JField("end", JInt(e)) :: JField("start", JInt(s)) :: Nil =>
          new Interval(start = s.longValue(), end = e.longValue())
      }
  },
  {
    case x: Interval =>
      JObject(JField("start", JInt(BigInt(x.startTime))) ::
        JField("end",   JInt(BigInt(x.endTime))) :: Nil)
  }
))

The idea is to sort the fields alphabetically, and then create the Interval class.

like image 91
AlexBrand Avatar answered Oct 18 '22 18:10

AlexBrand


I had a different but related issue that made me discover the the "extract" function in json4s. It solves the ordering issue.

case x: JObject =>
  Interval((x \ "start").extract[Int],(x \ "end").extract[Int])

If you need a more involved example, you can check this github ticket.

like image 23
John K Avatar answered Oct 18 '22 16:10

John K