由于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
}
*/
}
答案 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.
方法可用