用于蛇案例 ADT 的 ConfiguredJsonCodec
Posted
技术标签:
【中文标题】用于蛇案例 ADT 的 ConfiguredJsonCodec【英文标题】:ConfiguredJsonCodec for snake case ADT 【发布时间】:2020-12-08 12:39:46 【问题描述】:我必须使用一个 json api,其中有一个蛇案例中的离散字符串值列表。
以下示例有效,但我想删除手动 fooDecoder
以支持(当前已注释掉的)ConfiguredJsonCodec 注释。
或更基本的问题:将这些离散值建模为 ADT 中的案例对象是否有意义,或者是否有其他方法?
import io.circe._
import io.circe.syntax._
import io.circe.generic.extras.Configuration, ConfiguredJsonCodec, JsonKey
import io.circe.parser.parse
implicit val jsonConfig: Configuration = Configuration.default
.withSnakeCaseConstructorNames
.withSnakeCaseMemberNames
//@ConfiguredJsonCodec(decodeOnly = true)
sealed trait Foo
object Foo
case object FooBar extends Foo
case object FooBaz extends Foo
case object FooWuz extends Foo
import Foo._
implicit val fooDecoder: Decoder[Foo] = new Decoder[Foo]
override def apply(c: HCursor) = c.as[String].map
case "foo_bar" => FooBar
case "foo_baz" => FooBaz
case "foo_wuz" => FooWuz
@ConfiguredJsonCodec(decodeOnly = true)
case class Qux(fooFoo: List[Foo])
val input =""""foo_foo" : ["foo_bar", "foo_baz", "foo_wuz"]"""
val json: Json = parse(input).left.map(println(_)).right.get
json.as[Qux]
完整示例:https://scastie.scala-lang.org/eVFyNMGFRgaw9oEkRveT8g
这使用大约 0.13.0
【问题讨论】:
【参考方案1】:所有 Circe 联产品派生方法都假定存在歧视字段,您最多可以选择它的名称。所以支持的格式是这样的:
"type": "foo_bar",
而不仅仅是
"foo_bar"
原因是派生机制认为 case-object-only 和 case-object-and-case-classes 之间没有区别,所以对于这样的代码
trait MyADT
object MyADT
case class Value1(value: String) extends MyADT
case class Value2(value: String) extends MyADT
您只需将 sum 部分的编解码器组合在一起
val decoder: Decoder[MyADT] = Decoder[Value1].widen orElse Decoder[Value2].widen
即使您对Value2
进行了编码,您也总是会首先解码为Value1
。 Derivation 认为这两种情况之间没有区别,因此他们更愿意始终使用判别场来保证安全。 (这里是discussed in docs)。
但是,如果您知道自己正在构建枚举,则可以简单地使用带有 circe 支持的 enumeratum:
import enumeratum._
sealed trait Foo extends EnumEntry with Snakecase
object Foo extends Enum[Foo] with CirceEnum[Foo]
case object FooBar extends Foo
case object FooBaz extends Foo
case object FooWuz extends Foo
val values = findValues
这将实现您的目标,尽管方式不同。
【讨论】:
谢谢。不幸的是,我对我使用的 json 格式没有影响。不过我会考虑使用 enumeratum。以上是关于用于蛇案例 ADT 的 ConfiguredJsonCodec的主要内容,如果未能解决你的问题,请参考以下文章
在 jhipster 项目中将实体属性骆驼案例转换为 json 中的蛇案例