Re: [play-framework] [2.1-RC1-Scala] Json.reads and recursive case classes.

343 views
Skip to first unread message

Pascal Voitot Dev

unread,
Dec 6, 2012, 2:49:51 AM12/6/12
to play-fr...@googlegroups.com
Hi,
No, macro doesn't work with custom generic types in a recursive structure for the time being. It manages only recursive structure for option/list/set/map/... using lazyReads/lazyWrites and I can tell you, the corresponding macro code is quite complex.
Anyway, I must say I've never tried to simply write a Reads/Writes of this kind. I've spent lots of time on recursive structures but not on this one :D
Before we decide whether it is interesting to modify the macro to manage it (or not), could you try to test the case please?

import play.api.libs.functional.syntax._

id.lazyRead(idReads[C1]) and...

Best regards
Pascal



On Wed, Dec 5, 2012 at 2:58 PM, Ruud Diterwich <ru...@diterwich.com> wrote:
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

--
 
 

Pascal Voitot Dev

unread,
Dec 6, 2012, 10:59:24 AM12/6/12
to play-fr...@googlegroups.com
Do you have a code sample that I could test?
(just to be sure, there is no hidden bug)
Thanks
Pascal


On Thu, Dec 6, 2012 at 3:09 PM, Ruud Diterwich <ru...@diterwich.com> wrote:
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.

--
 
 

Ruud Diterwich

unread,
Dec 6, 2012, 11:30:23 AM12/6/12
to play-fr...@googlegroups.com
This is a complete example. Also noteworthy: case classes with a single parameters give different behaviour:

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!
}


Kind regards,

Ruud
Reply all
Reply to author
Forward
0 new messages