文字列または文字列のコレクションのみを含むケース クラスがあり、それらを対応するフィールド名と型を示す追加フィールドを持つ 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 とアルゴノートを試してみましたが、単純な使用シナリオが正当化するよりもはるかに多くのボイラープレートができてしまいました。
// 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))
これをより適切に処理できる別のライブラリはありますか、それとも私が見落としていたこれらのライブラリのいずれかにボイラープレートを大幅に削減する機能がありますか?