Json.asString возвращает None, хотя Json.toString возвращает правильное значение - PullRequest
0 голосов
/ 15 февраля 2019

Учитывая следующий класс дел LogMessage:

import io.circe.{Decoder, Encoder}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import enumeratum.{CirceEnum, Enum, EnumEntry}
import io.circe.syntax._

sealed trait LogLevel extends EnumEntry

object LogLevel extends Enum[LogLevel] with CirceEnum[LogLevel] {
  val values = findValues

  case object Warning extends LogLevel
  case object Error   extends LogLevel
  case object Info    extends LogLevel
  case object Success extends LogLevel
}

object LogMessage {
  implicit val logMessageDecoder: Decoder[LogMessage] = deriveDecoder[LogMessage]
  implicit val logMessageEncoder: Encoder[LogMessage] = deriveEncoder[LogMessage]
}

case class LogMessage(level: LogLevel, text: String, args: List[String], date: Long)
case class MyClass[A](obj: A)(implicit encoder: Encoder[A]) {
    def message1: String = obj.asJson.toString
    def message2: Option[String] = obj.asJson.asString
}

Почему это работает:

val x = MyClass(LogMessage(LogLevel.Info, "test notification", Nil, 1550218866571))

x.message1 // {\n  "level" : "Info",\n  "text" : "test notification",\n  "args" : [\n  ],\n  "date" : 1550218866571\n}

Но это не так:

x.message2 // None

Вот ссылка на Scastie с этой проблемой: ссылка .

1 Ответ

0 голосов
/ 15 февраля 2019

In circe Json имеет шесть asX методов, которые соответствуют шести типам данных в JSON.Например, если Json экземпляр x представляет логическое значение JSON, x.asBoolean вернет Some, содержащее значение в виде Boolean, но если x - это строка JSON, массив, объект, числоили ноль, x.asBoolean будет пустым.

Вы видите .asString return None в этом случае, потому что вы вызываете его для значения Json, которое представляет объект JSON, а нестрока JSON.

Метод toString в Json совершенно другой: это универсальный Scala / Java toString, который в случае Json реализован как .spaces2.Я не уверен, что вы пытаетесь сделать здесь, но в целом я бы рекомендовал избегать toString - если вы хотите сериализовать значение io.circe.Json, лучше использовать принтер или методы печати, которые делаютпараметры форматирования более явные (например, noSpaces, spaces2 и т.методы на Json. В целом в Circe «as» используется в именах методов для кодирования или декодирования, что не совсем то, что происходит в этих случаях, но достаточно близко, что я никогда не удосужился придумать лучшееальтернатива.)

...