Вы можете почти выполнить это с помощью общего деривации, используя конфигурацию в generic-extras:
sealed trait LimitOrWaiver
case class Limit(limitValue: String) extends LimitOrWaiver
case class Waived(waived: Boolean) extends LimitOrWaiver
case class Selection(medicalPayments: LimitOrWaiver)
import io.circe.generic.extras.Configuration, io.circe.generic.extras.auto._
import io.circe.syntax._
implicit val codecConfiguration: Configuration =
Configuration.default.withDiscriminator("type").withSnakeCaseMemberNames
А потом:
scala> Selection(medicalPayments = Limit("one_hundred")).asJson
res0: io.circe.Json =
{
"medical_payments" : {
"limit_value" : "one_hundred",
"type" : "Limit"
}
}
(Обратите внимание, что я также изменил имена членов класса case в Scala на идиоматический случай верблюда Scala и обрабатываю преобразование в случай змеи в конфигурации.)
Это не совсем то, что вам нужно, поскольку есть этот дополнительный элемент type
, но универсальный вывод circe поддерживает только кодирующие / декодирующие устройства с возможностью кругового обхода и без какого-либо дискриминатора - либо член, подобный этому, либо дополнительный объектный слой, который вы указали в вопросе - невозможно выполнить обход значений произвольных ADT через JSON.
Это может быть хорошо - вы можете не заботиться о дополнительных type
в вашем объекте. Если вам все равно, вы все равно можете использовать деривацию с небольшой дополнительной работой:
import io.circe.generic.extras.Configuration, io.circe.generic.extras.auto._
import io.circe.generic.extras.semiauto._
import io.circe.ObjectEncoder, io.circe.syntax._
implicit val codecConfiguration: Configuration =
Configuration.default.withDiscriminator("type").withSnakeCaseMemberNames
implicit val encodeLimitOrWaiver: ObjectEncoder[LimitOrWaiver] =
deriveEncoder[LimitOrWaiver].mapJsonObject(_.remove("type"))
И
scala> Selection(medicalPayments = Limit("one_hundred")).asJson
res0: io.circe.Json =
{
"medical_payments" : {
"limit_value" : "one_hundred"
}
}
Если вы действительно хотите, вы можете сделать это автоматически, так что type
будет удален из любых кодировщиков ADT, которые вы получите.