Search code examples
scalaplay-json

Writing custom object JSON as a simple value in Scala (JSON Reads/Writes)


I have a custom data type in Scala:

case class GPID(value: Int) {
    // ... other stuff ...

    implicit val writesGPID = new Writes[GPID] {
        def writes(g: GPID): JsValue = {
            Json.obj(
                "GPID" -> g.value
            )
        }
    }

    implicit val reads: Reads[GPID] = (
        (__ \ "GPID").read[Int]
        ).map(GPID(_))
}

As you can see, it has a reads/writes method, but this result in output like this:

"id":{"GPID":1000}

But, we just want it to serialize/deserialize like a regular Int:

"id":1000

I've been trying to figure out how to rewrite the reads/writes but am not having much luck... Any advice would be appreciated!

Thank you.


Solution

  • I added some validation, amend to your needs.

    object GPID {
      def unapply(in: Int): Option[GPID] = Option(in).filter(_ > 0).map(apply)
    
      implicit val reads = new Reads[GPID] {
        def reads(in: JsValue) =
          Option(in)
            .flatMap {
              case JsNumber(value) => Some(value)
              case _ => None
            }
            .flatMap(num => unapply(num.toInt))
            .map(JsSuccess(_, __))
            .getOrElse(JsError(__, "validate.error.expected.GPID"))
      }
    
      implicit val writes = new Writes[GPID] {
        def writes(g: GPID) = JsNumber(g.value)
      }
    
    }