Json4s custom serializer with unordered fields
Asked Answered
M

2

8

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)
Makell answered 24/7, 2014 at 20:50 Comment(0)
S
5

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.

Superdominant answered 8/5, 2015 at 16:4 Comment(0)
A
3

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.

Animation answered 31/10, 2015 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.