I've seen similar questions before, but none of them have worked. I think that they ask something different so I'm asking here. I have something like this in one file:
sealed trait Thing
case class SomeThing() extends Thing
case class OtherThing() extends Thing
and in another file:
val str = //valid json
val decoded = decode[Thing](str)
println(decoded)
and I get:
Left(DecodingFailure(...))
This works if I did:
val str = //valid json
val decoded = decode[SomeThing](str)
println(decoded)
I had to write own encoder and decoder for serialization/deserialization.
example,
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
object CirceSubtypesSerialisers {
  def main(args: Array[String]): Unit = {
    sealed trait Data
    case class OptionsData(data: Seq[String]) extends Data
    case class TextData(data: String) extends Data
    object Data {
      implicit val decodeData: Decoder[Data] = Decoder[OptionsData].map[Data](identity).or(Decoder[TextData].map[Data](identity))
      implicit val encodeData: Encoder[Data] = Encoder.instance {
        case options @ OptionsData(_) => options.asJson
        case text @ TextData(_) => text.asJson
      }
    }
    val optionsJson ="""{ "data": ["option1", "option2"] }""".stripMargin
    decode[Data](optionsJson) match {
      case Right(r: OptionsData) => println(r)
      case Left(l) => println(l)
    }
    val textJson ="""{ "data": "hey, how can i help ya?" }""".stripMargin
    decode[Data](textJson) match {
      case Right(r: TextData) => println(r)
      case Left(l) => println(l)
    }
  }
}
output:
OptionsData(List(option1, option2))
TextData(hey, how can i help ya?)
This is also mentioned in https://circe.github.io/circe/codec.html#warnings-and-known-issues and JsonCodec for sealed traits requires an explicit object definition
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With