Search code examples
scalaplay-json

Is there a way in Play JSON to define a reader for something that is not an object (/array)?


Basically, I have a JSON of this shape:

{
  "color": "#abcdef"
}

so I write a Reads:

import java.awt.Color

case class Options(color: Color)

((__ \ "color").read[Color])(Options _)

except there is no reader for Color. My second attempt was:

(
  Color.decode((__ \ "color").read[String])
)(Options _)

but that's also apparently not correct. The documentation show ways to create readers for { } (and [ ])'s, but not for "primitives" like numbers or strings. Can I do that?


Solution

  • You can do:

    case class Options(color: Color)
    
    object Options {
      implicit val colorReads: Reads[Color] = __.read[String].map(Color.decode)
      implicit val optionsReads: Reads[Options] = Json.reads[Options]
    }
    

    Then the usage is:

    val b = Json.parse("{ \"color\": \"#abcdef\"}").as[Options]
    println(b) // prints: Options(java.awt.Color[r=171,g=205,b=239])