如何使用Circe将缺少的JSON数组解码为空列表

时间:2019-06-16 00:13:53

标签: json scala circe

例如,我们有一些案例类

case class Foo(a: Int, b: List[String])

我们想从json Foo反序列化{"a": 1}的实例,用b替换丢失的Nil数组

我们可以为这种行为创建自定义解码器

implicit val fooDecoder: Decoder[Foo] = (c: HCursor) => 
  for {
    a <- c.downField("a").as[Int]
    b <- c.downField("b").as[Option[List[String]]
  } yield Foo(a, b.getOrElse(Nil))

但是,不幸的是,以这种方式创建的解码器并不会累积所有解码失败。

有没有办法创建带有错误累积的解码器,或者有什么办法替代标准列表反序列化行为?

2 个答案:

答案 0 :(得分:1)

尝试像这样使用b: List[String] = Nil提供defaultcirce-generic-extras

import io.circe.parser._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.auto._

implicit val config: Configuration = Configuration.default.withDefaults
case class Foo(a: Int, b: List[String] = Nil)
val raw = """{"a": 1}"""
decode[Foo](raw) // res0: Either[io.circe.Error,Foo] = Right(Foo(1,List()))

其中

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core" % "0.12.0-M3",
  "io.circe" %% "circe-parser" % "0.12.0-M3",
  "io.circe" %% "circe-generic-extras" % "0.12.0-M3",
  "io.circe" %% "circe-generic" % "0.12.0-M3"
)

答案 1 :(得分:0)

您也可以使用.map(_.getOrElse(List.empty))

implicit val fooDecoder: Decoder[Foo] = (c: HCursor) => 
  for {
    a <- c.downField("a").as[Int]
    b <- c.downField("b").as[Option[List[String]].map(_.getOrElse(List.empty))
  } yield Foo(a, b)