我如何配置 Circe 以停止使用嵌套的 class 名称作为编码 JSON 中的键名称?

How can I configure Circe to stop using nested class names as key names in encoded JSON?

我正在尝试对大小写 class 进行编码(其中某些属性也是大小写 classes),并且我正在获取嵌套的大小写 class 名称作为键JSON 中的名称。有没有一种简单的方法可以在不创建自定义编码器的情况下避免这种情况?嵌套的 classes 继承自密封特征。

我目前正在使用半自动推导。

以下工作表示例显示了我的问题:

case class A(foo: Int, bar: Sub)

sealed trait Sub
case class B(x: Int, y: Int) extends Sub
case class C(x: Int, y: Int, z: Int) extends Sub

import io.circe._, io.circe.generic.semiauto._
import io.circe.syntax._

implicit val bEncoder: Encoder[Sub] = deriveEncoder
implicit val aEncoder: Encoder[A] = deriveEncoder

A(123, B(8, 8)).asJson
A(456, C(8, 8, 8)).asJson

而不是得到:

res0: io.circe.Json = {
  "foo" : 123,
  "bar" : {
    "x" : 8,
    "y" : 8
  }
}
res1: io.circe.Json = {
  "foo" : 456,
  "bar" : {
    "x" : 8,
    "y" : 8,
    "z" : 8
  }
}

我得到

res0: io.circe.Json = {
  "foo" : 123,
  "bar" : {
    "B" : {
      "x" : 8,
      "y" : 8
    }
  }
}
res1: io.circe.Json = {
  "foo" : 456,
  "bar" : {
    "C" : {
      "x" : 8,
      "y" : 8,
      "z" : 8
    }
  }
}

我最终只是创建了自己的编码器。另一种选择是定义一个鉴别器,它可以采用 class 名称并将其设置为对象中的 属性,但我需要创建特定的 JSON 而无需任何其他属性。 如果其他人想这样做并且不介意 'type' 属性,请查看配置 class。

import io.circe.generic.extras.semiauto._
implicit val configuration: Configuration = 
  Configuration.default.withDiscriminator("type")
implicit val json: Encoder[FooBar] = deriveEncoder[FooBar]

记下从 extras 包中导入的 semiauto