我经常需要序列化/反序列化 sum 类型(如Either[S,T]
),但我还没有找到通用或优雅的方法来做到这一点。这是一个示例类型(基本上等同于Either
)
sealed trait OutcomeType
case class NumericOutcome(units: String) extends OutcomeType
case class QualitativeOutcome(outcomes: List[String]) extends OutcomeType
这是我在实现序列化的伴随对象上的最大努力。它可以工作,但是为每种 sum 类型一遍又一遍地写这些东西是非常令人厌烦的。有什么建议可以让它更好和/或更通用吗?
import play.api.libs.json._
import play.api.libs.functional.syntax._
object OutcomeType {
val fmtNumeric = Json.format[NumericOutcome]
val fmtQualitative = Json.format[QualitativeOutcome]
implicit object FormatOutcomeType extends Format[OutcomeType] {
def writes(o: OutcomeType) = o match {
case n@NumericOutcome(_) => Json.obj("NumericOutcome" -> Json.toJson(n)(fmtNumeric))
case q@QualitativeOutcome(_) => Json.obj("QualitativeOutcome" -> Json.toJson(q)(fmtQualitative))
}
def reads(json: JsValue) = (
Json.fromJson(json \ "NumericOutcome")(fmtNumeric) orElse
Json.fromJson(json \ "QualitativeOutcome")(fmtQualitative)
)
}
}