1

I have something like:

sealed trait Foo
case class Bar(field: ...) extends Foo
case class Baz(otherField: ...) extends Foo

trait JsonFormat {
  implicit val barWrites = Json.writes[Bar]
  implicit val barReads = Json.reads[Bar]

  implicit val bazWrites = Json.writes[Baz]
  implicit val bazReads = Json.reads[Baz]

  implicit val fooWrites = Json.writes[Foo]
  implicit val fooReads = Json.reads[Foo]

  // other vals that depend on Foo
}

When I compile, I get an error like:

[error] /file/path/JsonFormat.scala:68:41: unreachable code
[error]   implicit val fooWrites = Json.writes[Foo]
[error]                                       ^
[error] one error found

I'm pretty new to scala and I understand an "unreachable code" error in the context of pattern matching, but I can't figure this one out.

I'm using play 2.8.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
jsbg
  • 53
  • 7
  • 1
    In another thought, I don't understand why do you need the to declare `reads` and `writes` for `Foo`. It won’t work anyway. Take a look [here](https://scastie.scala-lang.org/toshetah/BRgGt5zpSAKCIpt6DyUKAQ) . Can you please elaborate what is the problem you are trying to solve? Here is a very similar question: https://stackoverflow.com/a/20616322/2359227 – Tomer Shetah Feb 01 '21 at 22:44
  • 1
    Let me agree with @TomerShetah. I've tried to reproduce issue on Scatie, but no luck so far: https://scastie.scala-lang.org/ZDeN4JSHQu2lKPa6Nlz0nQ – Ivan Kurchenko Feb 02 '21 at 06:41

1 Answers1

0

This may not be the exact solution to the answer but possible advice to change your approach.

First, if you add your own apply() method in your class's companion object this error does happen. Check that.

Second, the best practice seems to be that you would put an implicit converter within the companion object of the class per class and I'd go ahead and implicit the formatter so both conversion directions are supported.

case class SomeClass(someString: String)

object SomeClass {
    implicit val jsonFormatter: OFormat[SomeClass] = Json.format[SomeClass]
}

If you approach your JSON implicit converters this way, anywhere you use your DTOs will automatically get the implicit converter anywhere you use that class in both in and out directions.

Other place to assemble "shared" implicits is Package Object. I keep, for example, an ISO DateTime string <-> Date converter there.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Manabu Tokunaga
  • 956
  • 10
  • 19
  • I had this issue when `object SomeClass` had implemented an apply. Not yet sure why that happens, but you may want to check if that's the cause. Other than that, I do exactly what you do so all of my DTOs have js conversion implicits. Also be aware of 21 fields limit in Scala 2 `case` classes. – Manabu Tokunaga Mar 30 '21 at 00:22