Как использовать Circe Optics и Decode вместе - PullRequest
0 голосов
/ 26 апреля 2018

Я использую оптику Circe, подобную этой,

import io.circe.parser._
import io.circe.optics._
import io.circe.optics.JsonPath._

val json = parse("""{"response": {"person": {"firstname": "foo", "lastname":"bar"}}}""").right.get

Теперь я хочу извлечь объект всего лица в виде строки ... из этого json, например,

val p = root.response.person.string

, а затем декодироватьэто в класс case как

case class Person(firstname: String, lastname: String)
decode[Person](p.getOption(json).get)

Но это не работает, потому что root.response.person.string возвращает ноль.Я думаю, что это работает только для фактических строковых и целочисленных столбцов.

Так можно ли использовать оптическую систему для извлечения целых разделов json (например, объекта person внутри json)?и затем этот раздел декодируется в класс case?

1 Ответ

0 голосов
/ 26 апреля 2018

Это делается.Нет необходимости вставлять строку между ними, просто работайте с Json

object Some extends App {

  import io.circe.optics.JsonPath._
  import io.circe.parser._
  import io.circe._
  import io.circe.generic.semiauto._

  val json = parse("""{"response": {"person": {"firstname": "foo", "lastname":"bar"}}}""").right.get

  // this is just a lense to the person, not the person yet
  val personJsonPath = root.response.person.json

  case class Person(firstname: String, lastname: String)
  implicit val personDecoder: Decoder[Person] = deriveDecoder[Person]

  val maybePerson = personJsonPath
    // here you get the person out
    .getOption(json)
    // transforming json directly to case class, error handling should not be done like this ;)
    .map(_.as[Person].fold(throw _, identity))

  println(maybePerson)
}
...