5

環境

私は、階層内のアイテムであるケースクラスを持っています。これは、次のようにそれ自体を参照します。

case class Node(
  name:     String,
  children: Option[Seq[Node]] = None
)

これには PlayJsonFormatが必要です。

通常、次のことができます。

implicit lazy val formatter = Json.format[MyCaseClass]

しかし、これはうまくいきません。

なんで?

PlayJson は Scala マクロを使用してcaseFormatクラスのchildrenNode

No implicit format for Option[Seq[Node]] available.
[error]   implicit lazy val formatter = Json.format[Node]

質問

これにアプローチする最良の方法は何ですか?
これは PlayJson 形式のマクロの既知の問題ですか?

4

1 に答える 1

6

recursive typesこれはplay-json docsの下にあるものです:

import play.api.libs.functional.syntax._
import play.api.libs.json.{Reads, Writes, _}

case class Node(name: String, children: Option[Seq[Node]] = None)

implicit lazy val nodeReads: Reads[Node] = (
  (__ \ "name").read[String] and
  (__ \ "children").lazyReadNullable(Reads.seq[Node](nodeReads))
)(Node)

implicit lazy val nodeWrites: Writes[Node] = (
  (__ \ "name").write[String] and
  (__ \ "children").lazyWriteNullable(Writes.seq[Node](nodeWrites))
)(unlift(Node.unapply))

その場合Reads、 とWritesは対称であるため、全体を 1 つの として作成できますFormat

implicit lazy val nodeFormat: Format[Node] = (
  (__ \ "name").format[String] and
  (__ \ "children").lazyFormatNullable(Reads.seq[Node](nodeFormat), Writes.seq[Node](nodeFormat))
)(Node.apply, unlift(Node.unapply))
于 2016-06-23T13:06:32.583 に答える