Let's say your case class would be:
@JsonCodec(decodeOnly = true)
case class X(id: Int, text: String)
Then I could assume that your field would be of type:
type Mixed = X Either Int Either String
decode for which could look like:
implicit val mixedDecoder: Decoder[Mixed] =
Decoder[X].map[Mixed](x => Left(Left(x))) or Decoder[Int].map[Mixed](i => Left(Right(i))) or Decoder[String].map[Mixed](s => Right(s))
You could derive codecs for Either
if you define how they would be combined: left wins, right wins, or whatever you prefer:
implicit def eitherDecode[L: Decoder, R: Decoder]: Decoder[L Either R] =
Decoder[L].map[L Either R](Left(_)) or Decoder[R].map[L Either R](Right(_))
Alternatively, you can create your own ADT (sealed trait + case classes) and then writing handwritten decoder to avoid using discriminator field.
The bottom line is that you have to somehow express that polymorphism in the type you are decoding into (in a sane manner - Any
doesn't count) and then provide a decoder that would decode into it. And then you could simply use it:
@JsonCodec(decodeOnly = true)
case class BigClass(field1: String, value: Mixed)