可能会有一个看起来像这样的类:
case class Amount(value: Int)
case class Data(insurance: Option[Amount], itemPrice: Amount)
如果insurance = None
应该获得默认值waived: true
例如:
Data(Some(123),100).asJson
// output
{
"insurance": {
"value": 123
},
"price": 100
}
And when no Insurance is opted for:
Data(None,100).asJson
// output
{
"insurance": {
"waived: true
},
"price": 100
}
如何实现这种细粒度的控制?我尝试了各种招数用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
})
这很容易让我waived:true
胜任,但不知道如何处理Some(s)
此案。
如果具有{"waived": true}
预期的行为(Option[Amount]
如果为None),那么如果您编写用于以下目的的自定义编码器,则可以依靠半自动派生的编码器Option[Amount]
这是一个例子
import io.circe.{Encoder, Json}
import io.circe.syntax._
import io.circe.generic.semiauto._
case class Amount(value: Int)
case class Data(insurance: Option[Amount], itemPrice: Amount)
object Amount {
implicit val encoder: Encoder[Amount] = deriveEncoder
}
object Data {
implicit val encoderOptionalAmount: Encoder[Option[Amount]] = (optA: Option[Amount]) =>
optA match {
case Some(amount) => amount.asJson
case None => Json.obj("waived" -> true.asJson)
}
implicit val encoder: Encoder[Data] = deriveEncoder[Data]
}
println(Data(insurance = None, itemPrice = Amount(10)).asJson)
/*
{
"insurance" : {
"waived" : true
},
"itemPrice" : {
"value" : 10
}
}
*/
工作原理:deriveEncoder[Data]
将为itemPrice(类型Amount
)和保险类型调用隐式编码器Option[Amount]
。
默认编码器Option[T]
仅会跳过该值,None
但是由于我们为Option[T]
最近的作用域(数据对象伴随)定义了另一个隐式编码器,因此它不会在全局范围内寻找隐式编码器,从而为您提供所需的确切信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句