gpt4 book ai didi

json - 如何在 circe 中覆盖默认编解码器?

转载 作者:行者123 更新时间:2023-12-05 06:36:31 24 4
gpt4 key购买 nike

我想将案例类的 Array[Byte] 字段编码为 Base64 字符串。出于某种原因,Circe 没有使用默认编解码器选择我的编解码器,而是将字节数组转换为 json 整数数组。

我应该怎么做才能修复它?这是我最小化的代码

import io.circe.generic.JsonCodec

sealed trait DocumentAttribute

@JsonCodec
sealed case class DAAudio(title: Option[String], performer: Option[String], waveform: Option[Array[Byte]], duration: Int) extends DocumentAttribute

@JsonCodec
sealed case class DAFilename(fileName: String) extends DocumentAttribute

object CirceEncodersDecoders {
import io.circe._
import io.circe.generic.extras._
import io.circe.generic.extras.semiauto._

implicit val arrayByteEncoder: Encoder[Array[Byte]] = Encoder.encodeString.contramap[Array[Byte]] { bytes ⇒
Base64.getEncoder.encodeToString(bytes)
}

val printer: Printer = Printer.noSpaces.copy(dropNullValues = true, reuseWriters = true)
implicit val config: Configuration = Configuration.default.withDiscriminator("kind").withSnakeCaseConstructorNames.withSnakeCaseMemberNames

implicit val DocumentAttributeEncoder: Encoder[DocumentAttribute] = deriveEncoder
implicit val DocumentAttributeDecoder: Decoder[DocumentAttribute] = deriveDecoder
}

object main {
def main(args: Array[String]): Unit = {
import CirceEncodersDecoders._

import io.circe.parser._
import io.circe.syntax._

val attributes: List[DocumentAttribute] = List(
DAAudio(Some("title"), Some("perform"), Some(List(1, 2, 3, 4, 5).map(_.toByte).toArray), 15),
DAFilename("filename")
)
val j2 = attributes.asJson
val decoded2 = decode[List[DocumentAttribute]](j2.noSpaces)
println(decoded2)
}
}

最佳答案

当你这样做时:

implicit val DocumentAttributeEncoder: Encoder[DocumentAttribute] = deriveEncoder

circe 尝试为 DAFilenameDAAudio 获取合适的Encoder。但是,由于那些已经存在(通过 @JsonCodec 在各个类上),它不会使用泛型和您的 Encoder[Array[Byte]] 从头开始​​重新派生它们> 在范围内 - 你想要的。

因此您可以摆脱 @JsonCodec(因此它会自动派生 DAFilenameDAAudio 以及 DocumentAttribute 的编解码器) 或手动触发重新推导:

implicit val AudioDecoder: Encoder[DAAudio] = deriveEncoder // takes priority over existing one
implicit val DocumentAttributeEncoder: Encoder[DocumentAttribute] = deriveEncoder // AudioDecoder will be used here

您还需要为Array[Byte] 构建一个Decoder 并为Decoder 重复上面的过程,否则它会尝试将 Base64 字符串解析为整数列表,导致失败。

关于json - 如何在 circe 中覆盖默认编解码器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49047509/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com