I'm trying to use the reader/combinator things to parse an array that contains mixed data-types, but I'm not sure how to specify a reader for such a thing. I have some JSON like this:
{
"stuff": [1, 2, true, null, "false", "hahaha", 5, "8"]
}
I want to parse all of this into a string-representation, but when I just try to use a reader of List[String]
I get parse exceptions. I imagine something like this:
implicit val mixedArrayReader = (
(__ \ 'not).readNullable[List[JsValueWrapper]].map(opt => opt.map(list =>
list.map { wrapper : JsValueWrapper =>
val parsed : String = wrapper match {
case b : JsBoolean => if (b.value) "1" else "0"
case n : JsNumber => n.value.toString
case s : JsString => s.value
case JsNull => "null"
case u => u.toString // unknown
}
parsed
}
))
)
However, since there is no reader for JsValueWrapper
, I'm not sure where to go from here. Any help is greatly appreciated.
Thanks!
Start by implementing a customized Reads[String], then use Reads.list
to turn it into a reader of List[String]
, then use that reader as usual. Prefer to pass those particular readers explicitly versus defining implicits for them in order to not hide Play's default Reads[String]
.
import play.api.libs.json.Reads
val myReader: Reads[String] = Reads[String](value => JsSuccess(value match {
case b : JsBoolean => if (b.value) "1" else "0"
case n : JsNumber => n.value.toString
case s : JsString => s.value
case JsNull => "null"
case u => u.toString // unknown
}))
val listReads = Reads.list[String](myReader)
Then, in a combined reader you can write something like:
implicit val objReader =
(__ \ 'not).readNullable(listReads)