Расшифровка последовательности объектов с помощью Circe

У меня есть два класса, которые выглядят примерно так

import io.circe.Decoder

case class FactResponse(id: String, status: String) {
  ...
}


object FactResponse {

  implicit val decoder: Decoder[FactResponse] =
    Decoder.forProduct2("id", "status")(FactResponse.apply)

  def apply(json: String): FactResponse = {
    import io.circe.parser.decode
    decode[FactResponse](json).right.get
  }
}    



case class RuleEngineRequestResponse(content: Seq[Map[String, String]])

object RuleEngineRequestResponse {

  implicit val decoder: Decoder[RuleEngineRequestResponse] =
    Decoder.forProduct1("content")(RuleEngineRequestResponse.apply(_: String))

  def apply(json: String): RuleEngineRequestResponse = {
    import io.circe.parser.decode
    println("here")
    print(json)
    println(decode[RuleEngineRequestResponse](json).left.get)
    decode[RuleEngineRequestResponse](json).right.get
  }
}

Я пытаюсь расшифровать json, который выглядит примерно так

{"content": [{"id": "22", "status": "22"]}

Однако я получаю ошибку декодирования DecodingFailure (String, downfield ("content"))

Я не совсем уверен, что здесь происходит не так, json определенно правильный, я даже пытался разобрать контент на последовательность карт, но, тем не менее, я получаю одно и то же снова и снова. есть идеи о том, как анализировать вложенные объекты как массив с помощью circe?


person Niro    schedule 30.10.2018    source источник
comment
Некоторые рекомендации: Импорт всегда должен быть поверх файла. .right, .left и .get - вообще плохая идея, когда речь идет о функциональном программировании.   -  person Markus Appel    schedule 30.10.2018


Ответы (1)


Я думаю, вы можете значительно упростить декодирование, если позволите Circe автоматически выводить декодеры:

import io.circe.generic.auto._
import io.circe.parser.decode

case class FactResponse(id: String, status: String)
case class RuleEngineRequestResponse(content: Seq[FactResponse])

object Sample extends App {
  val testData1 =
    """
      |{
      |   "content":[
      |      {
      |         "id":"22",
      |         "status":"22"
      |      }
      |   ]
      |}""".stripMargin

  val testData2 =
    """
      |{
      |   "content":[
      |      {
      |         "id":"22",
      |         "status":"22"
      |      },
      |      {
      |         "id":"45",
      |         "status":"56"
      |      }
      |   ]
      |}""".stripMargin

  println(decode[RuleEngineRequestResponse](testData1))
  println(decode[RuleEngineRequestResponse](testData2))

}

Это выводит:

Right(RuleEngineRequestResponse(List(FactResponse(22,22))))
Right(RuleEngineRequestResponse(List(FactResponse(22,22), FactResponse(45,56))))

Вам нужно будет включить зависимости:

  "io.circe" %% "circe-generic" % circeVersion,
  "io.circe" %% "circe-parser"  % circeVersion,

Я использовал версию circe 0.10.0

Вы можете проверить это здесь.

person Damien O'Reilly    schedule 30.10.2018