0

I am trying to migrate to the latest version of upickle 0.7.1. Where I had previously passed around implicit Readers and Writers I believe I must now use a single ReadWriter and explicitly define them in a companion object for any case classes I want to serialize. But I cannot figure out how this works for a parameterized type. So for example say I had the following before upgrading (from 0.4.4):

trait OldTrait[T] {

    implicit val evr: Reader[T]
    implicit val evw: Writer[T]

    def save(t: T): String = write(t)
    def restore(str: String): T = read[T](str)
}

class MyOldClass[T](implicit val evr: Reader[T], val evw: Writer[T]) extends OldTrait[T] {
}

case class Request[T](msg: T)

val c1 = new MyOldClass[Request[Int]]

The above code compiled fine for me. To migrate this code I have tried the following:

trait NewTrait[T] {
    implicit val evrw: ReadWriter[T]
}

class MyNewClass[T](implicit val evrw: ReadWriter[T]) extends NewTrait[T] {

}

object Request {
    implicit val rw: ReadWriter[Request[_]] = macroRW
}

val c2 = new MyNewClass[Request[Int]]

But this will not compile for me. I get the following errors:

Don't know how to derive type ...Request[] implicit val rw: ReadWriter[Request[]] = macroRW

... could not find implicit value for parameter evrw: upickle.default.ReadWriter[Request[Int]]

...not enough arguments for constructor MyNewClass: (implicit evrw: upickle.default.ReadWriter[Request[Int]])MyNewClass[Request[Int]]. Unspecified value parameter evrw. val c2 = new MyNewClass[Request[Int]]

What would be the correct approach to migrating the old code?

user79074
  • 4,937
  • 5
  • 29
  • 57
  • are you sure it worked with upickle 0.4.4? It does not compile for me, giving an error: `could not find implicit value for parameter evr: upickle.default.Reader[ammonite.$sess.cmd5.Request[Int]] val c1 = new MyOldClass[Request[Int]] ^ Compilation Failed` – Alexey Novakov Feb 04 '19 at 21:09
  • Yes tested again and compiles fine in 0.4.4. But if I use version 0.7.1 I get that same error. Maybe you compiled with a later version? – user79074 Feb 04 '19 at 22:16

1 Answers1

2

Not tested, but I would expect you need

implicit def rw[T: ReadWriter]: ReadWriter[Request[T]] = macroRW

So e.g. because there is a ReadWriter[Int], there's also a ReadWriter[Request[Int]].

(I would be very surprised if this doesn't work, but you can certainly do it manually instead of macroRW in this case.)

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487