Scala & Circe: JSON кодирование с дополнительными полями - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь использовать Circe для выполнения некоторой кодировки JSON следующим образом:

import io.circe.{Encoder, Json}
import io.circe.syntax._

case class Person(name: String, nickname: Option[String] = None)

object EncodingTest extends App {
  val persons = List (Person("John", None), Person("Tania", Some("Awesome")))

  implicit val encodePerson: Encoder[Person] = (p: Person) => {
    Json.obj(
      ("name", Json.fromString(p.name)),
      ("nickname", Json.fromString(p.nickname.getOrElse(""))) // <- Problem is here
    )
  }

  for(person <- persons)
    println(person.asJson)
}

В идеале я хотел бы получить следующий вывод:

{"name":"John"}
{"name":"Tania","nickname":"Awesome"}

Как можно Я заставляю кодировщик пропускать поле nickname в случае, если значение поля равно None?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Если вы хотите определить пользовательские кодировщики и не полагаться на полуавтоматическое выполнение следующих работ

import io.circe.{Encoder, Json}
import io.circe.syntax._

object CirceOptional extends App {

  case class Person(name: String, nickname: Option[String] = None)

  val encodePerson: Encoder[Person] = (p: Person) => {
    Json.obj(("name", p.name.asJson), ("nickname", p.nickname.asJson))
  }

  implicit val noNullEncoder: Encoder[Person] = encodePerson.mapJson(_.dropNullValues)

  val persons = List (Person("John", None), Person("Tania", Some("Awesome")))

  for(person <- persons)
    println(person.asJson)

}
1 голос
/ 08 апреля 2020

Самый простой способ - просто собрать интересующие вас поля

Json.obj(List(
  ("name", Some(Json.fromString(p.name))),
  ("nickname", p.nickname.map(Json.fromString))
).collect {
  case (name, Some(value)) => name -> value
}: _*)

Больше автоматов c способ получить то, что вы хотите:

import io.circe.generic.semiauto._
implicit val encodePerson: Encoder[Person] = deriveEncoder
person.asJson.dropNullValues
...