Как декодировать ноль в пустую строку в Circe

У меня есть следующий класс дела

case class Response(attributes: CsvAttributes, rows: Seq[Array[String]])

rows получены из библиотеки Java, которая может иметь нулевые элементы в массиве, как показано ниже:

[
  ["a", "b", null],
  ["c", null, "d"]
]

Response(attributes, rows).asJson.noSpaces выдает ошибку.

Как закодировать нулевые элементы в пустую строку ("")?

2 ответа

Решение

Вы можете использовать собственный декодер для Response:

implicit val decodeResponse: Decoder[Response] = (c: HCursor) =>
  for {
    attributes <- c.downField("attributes").as[CsvAttributes]
    rows       <- c.downField("rows").as[Seq[Array[Option[String]]]]
  } yield {
    Response(attributes, rows.map(_.map {
      case Some(v) => v
      case None    => ""
    }))
  }

Я хотел бы попытаться перевести ответ из вашей библиотеки Java на идиоматический Scala (например, перевести null в Option.None).

Но если вы хотите избежать этого, вы можете переписать поведение по умолчанию того, как Circe кодирует String, Эта декларация изменит ее для представления null с пустой строкой:

implicit val encodeFoo: Encoder[String] = {
  case null => Json.fromString("")
  case s    => Json.fromString(s)
}

Еще один быстрый и грязный подход:

implicit val encodeString = 
  Encoder.encodeString.contramap[String](s => if (s == null) "" else s)
Другие вопросы по тегам