Допустим, ваш класс case будет:
@JsonCodec(decodeOnly = true)
case class X(id: Int, text: String)
Тогда я мог бы предположить, что ваше поле будет иметь тип:
type Mixed = X Either Int Either String
decode, для которого может выглядеть:
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))
Вы можете вывести кодеки для Either
, если вы определите, как они будут сочетаться: победа слева, победа справа или что угодно, что вам больше нравится:
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(_))
В качестве альтернативы вы можете создать свой собственный ADT (запечатанные признаки + классы регистра), а затем написать рукописный декодер, чтобы избежать использования поля дискриминатора.
Суть в том, что вам нужно как-то express этот полиморфизм в типе, который вы декодируете (в разумным образом - Any
не считается), а затем предоставить декодер, который будет декодировать его. И тогда вы можете просто использовать его:
@JsonCodec(decodeOnly = true)
case class BigClass(field1: String, value: Mixed)