Scala 如何使用Circe创建选项类型的自定义编码?

Scala 如何使用Circe创建选项类型的自定义编码?,scala,circe,Scala,Circe,有可能有这样一个类: case class Amount(value: Int) case class Data(insurance: Option[Amount], itemPrice: Amount) 如果insurance=None它应该得到默认值放弃:true 例如: 如何实现这种细粒度控制?我用forProduct2和mapJsonObject尝试了各种技巧,但无法使其正常工作: implicit val testEncoder = deriveEncoder[Option[Amou

有可能有这样一个类:

case class Amount(value: Int)
case class Data(insurance: Option[Amount], itemPrice: Amount)
如果
insurance=None
它应该得到默认值
放弃:true

例如:

如何实现这种细粒度控制?我用
forProduct2
mapJsonObject
尝试了各种技巧,但无法使其正常工作:

implicit val testEncoder = deriveEncoder[Option[Amount]].mapJsonObject(j => {

    val x = j("Some") match {
      case Some(s) => // need to convert to [amount -> "value"]
      case None => JsonObject.apply(("waived",Json.fromBoolean(true)))
    }

    x
  })
这很容易让我得到
放弃:true
部分,但不知道如何处理
一些案例

如果任何
选项[Amount]
的预期行为是
{“弃权”:true}
,如果没有,那么如果您为
选项[Amount]
编写自定义编码器,您可以依赖半自动派生编码器

这里有一个例子

import io.circe.{Encoder,Json}
导入io.circe.syntax_
导入io.circe.generic.semiauto_
案例类别金额(值:Int)
案例类别数据(保险:选项[金额],项目价格:金额)
对象数量{
隐式val编码器:编码器[金额]=deriveEncoder
}
对象数据{
隐式val EncodeProptionalAmount:Encoder[Option[Amount]]=(optA:Option[Amount])=>
optA匹配{
case Some(amount)=>amount.asJson
case None=>Json.obj(“放弃”->true.asJson)
}
隐式val编码器:编码器[数据]=deriveEncoder[数据]
}
println(数据(保险=无,项目价格=金额(10)).asJson)
/*
{
“保险”:{
“放弃”:正确
},
“项目价格”:{
“价值”:10
}
}
*/
工作原理:
deriveEncoder[Data]
将为itemPrice(类型
Amount
)和保险类型
选项[Amount]
调用隐式编码器


Option[T]
的默认编码器在
None
时跳过该值,但由于我们在最近的作用域(数据对象伴侣)中为
Option[T]
定义了另一个隐式编码器,因此它不会在全局作用域中查找隐式编码器,从而提供您想要的内容。

这是一个有趣的模式。让我试试。可能对“其他”问题也有帮助:)如果为选项[Amount]设置编码器不适合您(没有双关语),请告诉我。我还有另一个解决方案,不过我还是要加上它。这可能有助于解决“如果”的情况,在某些地方,我们只需要选择。没有
implicit val testEncoder = deriveEncoder[Option[Amount]].mapJsonObject(j => {

    val x = j("Some") match {
      case Some(s) => // need to convert to [amount -> "value"]
      case None => JsonObject.apply(("waived",Json.fromBoolean(true)))
    }

    x
  })