Простая библиотека Scala JSON для нерекурсивных классов

У меня есть классы дел, которые содержат только строки или коллекции строк и хотят преобразовать их в объекты JSON с соответствующими именами полей плюс дополнительное поле для обозначения типа.

sealed trait Item
case class ProductX(a: String, b: String) extends Item
case class ProductY(a: String, b: String) extends Item
case class CollX(els: List[String]) extends Item
case class CollY(els: List[String]) extends Item

Большинство библиотек имеют специальную поддержку для классов дел, но, кажется, никогда не существует способа использовать его в сочетании с дополнительным полем типа для устранения неоднозначности изоморфных дел, и мне пришлось бы вернуться к более низкоуровневым описаниям.

До сих пор я пробовал спрей-json и argonaut, и у меня получилось гораздо больше шаблонного примера, чем мой простой сценарий использования:

// spray-json

implicit object CollXJsonFormat extends RootJsonFormat[CollX] {
  def write(ss: CollX) = JsObject(
    "type" -> JsString("CollX"),
    "els"  -> JsArray(ss.els.map(JsString(_)): _*)
  )
  def read(value: JsValue) = {
    value.asJsObject.getFields("type", "els") match {
      case Seq(JsString("CollX"), JsArray(els)) =>
        CollX(els.toList.map({
          case JsString(s) => s
          case _ => throw new DeserializationException("JsString expected")
        }))
      case _ => throw new DeserializationException("CollX expected")
    }
  }
}

Для аргонавта я даже не мог понять, как сопоставить поле типа, так как DecodeResult не имеет метода фильтрации:

// argonaut

implicit def CollXCodec: CodecJson[CollX] =
  CodecJson(
    (px: CollX) =>
      ("type" := "CollX") ->:
      ("els" := px.els) ->:
      jEmptyObject,
    c => for {
      t <- (c --\ "type").as[String]
      els <- (c --\ "els").as[List[String]]
    } yield CollX(els))

Есть ли другая библиотека, которая может справиться с этим лучше, или есть какая-то особенность в одной из этих библиотек, которую я упустил из виду, которая значительно уменьшит шаблон?

1 ответ

Я использую: net.liftweb с очень хорошими результатами.

Вы можете создать JSON таким образом. Например, если у вас есть:

case class ABjsontemplate(a: String, b: String)

Вы можете создать JSON, как это:

net.liftweb.json.Serialization.write(ABjsontemplate("a", "b"))

в SBT:

libraryDependencies += "net.liftweb" %% "lift-json" % "3.0-M1"

Я надеюсь, что это может помочь.

Другие вопросы по тегам