Hi all,How can I create a Reads object for a recursive case class? This is what I have:
case class C1(id : Id[C1] = Id.generate, name : String)
implicit def idReads[A] = Reads[Id[A]] { jsValue => JsSuccess(Id[A](jsValue.toString)) }implicit val c1Reads = Json.reads[C1]I get an compile error on the 3th line (very long error): overloaded method value apply .....cannot be applied to (....C1.type)
The reason for my Id class is to have typed entity ids. It's just a typed wrapper around a string.When I use Option[C1] instead of Id[C1] it works.When I use Id[String] instead of Id[C1] it works.When I use Id[XXX] instead of Id[C1] it works.Probably, my idReads definition is wrong...Could someone show me the way?Thanks!Ruud--
Strange thing is, the normal expanded form seems to compile fine:implicit val c1Reads2: Reads[C1] = (
(__ \ "id").read[Id[C1]] and(__ \ "name").read[String]
)(C1)
as does:implicit val c1Reads3 : Reads[C1] = (
(__ \ "id").lazyRead(idReads[C1]) and
(__ \ "name").read[String]
)(C1)
Note that I don't actually need recursion, since Id is just a typed string.
--
package jsontest
import play.api.libs.json.__
import play.api.libs.json.Json
import play.api.libs.json.Reads
import play.api.libs.json.JsSuccess
import play.api.libs.functional.syntax._
// Implicitly needed, can't macro import this automatically?
import play.api.libs.json.JsPath
case class Id[A](id: String)
case class C1(id: Id[C1])
case class C2(id: Id[C2], name : String)
package object json {
implicit def idReads[A] = Reads[Id[A]] { jsValue => JsSuccess(Id[A](jsValue.toString)) }
val c1Reads1 = Json.reads[C1] // Compile error
val c1Reads2 = (
(__ \ "id").read[Id[C1]]
)(C1) // Compile error
val c2Reads1 = Json.reads[C2] // Compile error
val c2Reads2 = (
(__ \ "id").read[Id[C2]] and
(__ \ "name").read[String]
)(C2) // OK!
}