如何使用 circe 定义一些通用解码器/编码器?

问题描述

假设我定义了多种类型的 ID,如下所示。

sealed trait Id {
  val value: String
}
case class IdA(value: String) extends Id
case class IdB(value: String) extends Id
case class IdC(value: String) extends Id

这些类应该从以下 JSON 解码和编码。

 {
    "id: "some-id"
 }

如何为 id 定义一些通用的解码器/编码器,

case class A(id: IdA,name: String,count: Int)
case class B(id: IdB,count: Int)
case class C(id: IdC,count: Int)

这样上面的类就可以从下面的 JSON 解码并编码到下面的 JSON 了吗?

{
   "id" : "some-id","name": "some-name","count": 2
}

如果可能,我希望 id 字段对于解码器和编码器都具有灵活性,在一种情况下 id 可能是“id-x”,而在另一种情况下可能是“id-y”。

解决方法

我通过简单地定义以下解码器和编码器来解决它。

import cats.implicits._
import io.circe.{Decoder,Encoder}
import shapeless._

 implicit def encoderValueClass[T <: Id,V](implicit
      g: Lazy[Generic.Aux[T,V :: HNil]],e: Encoder[V]
  ): Encoder[T] = Encoder.instance { value =>
    e(g.value.to(value).head)
  }

  implicit def idDecoder[T <: Id,d: Decoder[V]
  ): Decoder[T] = Decoder.instance { cursor =>
    d(cursor).map { value =>
      g.value.from(value :: HNil)
    }
  }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...