Нужна помощь в декодировании следующего json с помощью Circe

Я пытаюсь разобрать вложенный объект JSON с библиотекой Circe. Я хотел бы сопоставить его с классом плоского корпуса, игнорируя некоторые поля.

import io.circe.generic.auto._
import io.circe.{Decoder, Encoder, HCursor, Json}

val jsonString = """{
  "parent" : {
    "name" : "title",
    "items" : [
      {
        "foo" : "",
        "attrs" : {
          "attrA" : "",
          "attrB" : ""
        }
      },
      {
        "foo" : "",
        "attrs" : {
          "attrA" : "",
          "attrB" : "",
          "attrC" : ""
        }
      }]
    }
}"""


// Notice I don't care about "attrC"
case class Item(foo: String, attrA: String, attrB: String)
case class Parent(name: String, items: List[Item])

implicit val testDecoder: Decoder[Item] = Decoder.instance { c =>
    val itemsC = c.downField("parent").downField("items")

    for {
      foo <- itemsC.get[String]("foo")
      a <- itemsC.downField("attrs").get[String]("attrA")
      b <- itemsC.downField("attrs").get[String]("attrB")
    } yield Item(foo, a, b)
  }

val decodingResult = parser.decode[Parent](jsonString)

результат: Either[io.circe.Error,Parent] = Left(DecodingFailure(Attempt to decode value on failed cursor, List(DownField(name))))


person marcin_koss    schedule 01.12.2018    source источник
comment
Что уже пробовали? Код?   -  person cchantep    schedule 01.12.2018


Ответы (1)


Мне проще использовать автоматический анализатор, получить данные в Scala и продолжить оттуда.

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

val sample="""{
  "parent" : {
    "name" : "title",
    "items" : [
      {
        "foo" : "",
        "attrs" : {
          "attrA" : "",
          "attrB" : ""
        }
      },
      {
        "foo" : "",
        "attrs" : {
          "attrA" : "",
          "attrB" : "",
          "attrC" : ""
        }
      }
      ]
    }
  }"""


case class Data(parent : Parent)
case class Parent(name: String, items: List[Item])
case class Item(foo: String, attrs : Attrs)
case class Attrs(attrA: String, attrB: String) // you don't need attributes you don't use
val data=decode[Data](sample)
person Arnon Rotem-Gal-Oz    schedule 01.12.2018
comment
Выглядит неплохо, хотя я бы все же избегал вспомогательных классов case :) - person marcin_koss; 02.12.2018
comment
Как я уже сказал, как только он у вас есть в Scala, его легко преобразовать во что угодно (проще, чем писать собственный декодер, ИМХО) - person Arnon Rotem-Gal-Oz; 02.12.2018