JsonCodec for sealed traits requires an explicit object definition
See original GitHub issueAs reported by @ngbinh, the following does not compile in circe 0.4.0-RC1:
import io.circe.generic.JsonCodec
@JsonCodec sealed trait A
case class B(b: String) extends A
case class C(c: Int) extends A
The expanded version fails as well:
import io.circe.{ Decoder, Encoder }
sealed trait A
object A {
implicit val encodeA: Encoder[A] = io.circe.generic.semiauto.deriveEncoder[A]
implicit val decodeA: Decoder[A] = io.circe.generic.semiauto.deriveDecoder[A]
}
case class B(b: String) extends A
case class C(c: Int) extends A
But can be fixed by moving the object A
definition after the case class definitions.
Similarly, it’s possible to work around the issue with @JsonCodec
by adding an object definition (potentially empty) after the case classes:
import io.circe.generic.JsonCodec
@JsonCodec sealed trait A
case class B(b: String) extends A
case class C(c: Int) extends A
object A
This isn’t that terrible, but it’s an annoying thing to have to remember. I’m not sure we can fix the JsonCodec
macro annotation so that this workaround isn’t necessary, but we should at least take a look (probably after the 0.4.0 release).
Issue Analytics
- State:
- Created 7 years ago
- Comments:20 (13 by maintainers)
Top Results From Across the Web
JsonCodec for sealed traits requires an explicit object definition
JsonCodec for sealed traits requires an explicit object definition. ... JsonCodec @JsonCodec sealed trait A case class B(b: String) extends A case class ......
Read more >Circe Decode to sealed trait extended by multiple case classes
_ object CirceSubtypesSerialisers { def main(args: ... and JsonCodec for sealed traits requires an explicit object definition.
Read more >circe/circe - Gitter
alternately if you're explicitly passing encode rather than using implicit ... sealed trait MyType object MyType { case object SomeType extends MyType case ......
Read more >Warnings and known issues - circe
Generic derivation may not work as expected when the type definitions that you're ... _ scala> sealed trait A; case object B extends...
Read more >Introduction to Traits in Scala - Baeldung
A musical score needs to have a composition. Let's begin by creating a Composition trait: trait Composition { var composer: String def ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The exact static type always determines which instance will be used, and circe-generic will always give different instances for
A
andB
here.If you wanted instances for
A
that didn’t use the object wrapper, you could do something this:And then:
This isn’t the default because in some cases it can lead to ambiguity in decoding, but if your case class member names don’t overlap it can be a reasonable thing to do.
Is it supposed to work if I nest the case classes inside the sealed trait’s companion?