使用Play Json

时间:2017-06-19 08:37:01

标签: scala play-json

由于22字段限制,我不得不将大型案例类拆分为较小的类。如何压扁这个大班的Writes

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class B(x: Option[Int], y: Option[Int])

object B {
  implicit val format: (Reads[B], Writes[B]) => Format[B] = Format[B]
}

case class C(z: Option[Int], w: Option[Int])

object C {
  implicit val format: (Reads[C], Writes[C]) => Format[C] = Format[C]
}

case class A(b: B, c: C)

object A {
  implicit val reads: Reads[A] =
    (Reads.of[B] and Reads.of[C]) (A.apply _)

  implicit val writes: Writes[A] = ???
  /*
  val a = A(B(1, 2), C(3, 4)

  Json.toJson(a) should be

  {
    "x": 1
    "y": 2
    "z": 3
    "w": 4
  }
   */
}

1 个答案:

答案 0 :(得分:1)

简短的故事,你可以这样做:

implicit val writes: Writes[A] = JsPath.write[B].and(JsPath.write[C]) (unlift(A.unapply _))

长篇故事:为什么你能使用and方法?

and可用于实现类型类FunctionalCanBuild的任何类。到目前为止我注意到的是Writes没有这样的类型类,但OWrites有一个。

使用JsPath.write[B]会产生OWrites值,因此可以使用and方法。另一方面,使用Writes.of[]会产生Writes,而OWrites.of[]会产生Writes[]。最后,获得OWrites[]的任何方法都允许您使用关键字和。

此外,进一步研究代码,Applicative类型类的任何实例都可以转换为FunctionalCanBuild的实例。此类型类是针对任何Reads实现的,因此and

上的Readers.方法可用