2

The experimental "Inception" feature in Play 2.1 (Json.format[...]) only works for case classes (see here). How can I write my custom format implicit for a trait. I have the following construct:

sealed trait Plan {
  def id: String
  def name: String
  def apps: Int
  def users: Int
  def testruns: Int
  def price: Int
  def prio: Int
}

And the following case classes which are extending the trait Plan.

case class Start(
                  id: String = "start",
                  name: String = "Start",
                  apps: Int = 1,
                  users: Int = 1,
                  testruns: Int = 10,
                  price: Int = 99,
                  prio: Int = 30) extends Plan

case class Pro(
                id: String = "pro",
                name: String = "Pro",
                apps: Int = 2,
                users: Int = 5,
                testruns: Int = 25,
                price: Int = 299,
                prio: Int = 20) extends Plan

case class Premium(
                    id: String = "premium",
                    name: String = "Premium",
                    apps: Int = -1,
                    users: Int = -1,
                    testruns: Int = -1,
                    price: Int = 799,
                    prio: Int = 10) extends Plan

Now I need to write my custom implicit format val in the Plan companion object. I tried:

object Plan {
  implicit val planFormats = (
    (__ \ "id").format[String] and
    (__ \ "name").format[String] and
    (__ \ "apps").format[Int] and
    (__ \ "users").format[Int] and
    (__ \ "testruns").format[Int] and
    (__ \ "price").format[Int] and
    (__ \ "prio").format[Int]
  )(Plan.apply, unlift(Plan.unapply))
}

However, a trait hasn't an apply or unapply method. What is the correct way to provide an implicit val for the json serialization in Play 2.1?

4

2 回答 2

5

您只需提供自己的函数,从给定的值创建一个新实例。

本质上是作为工厂的特征的伴随对象。

object Plan {
  def apply(id: String, name: String, ...) = id match {
    case "pro" => new Pro(id, name, ...)
    ...
  }

  def unapply(p: Person): Option[(String, String, ...)] = ...
}
于 2013-05-06T07:16:19.093 回答
1

为什么要使用 Traits 并实施案例类?

为什么不使用类的实例,例如:

case class Plan (
  id: String,
  name: String,
  apps: Int,
  users: Int,
  testruns: Int,
  price: Int,
  prio: Int
)

val start = new Plan("start", "Start", 1, 1, 10, 99, 30)
val pro = new Plan("pro", "Pro", 2, 5, 25, 299, 20)
val premium = new Plan("premium", "Premium", -1, -1, -1, 799, 10)

然后,您可以保留您的 Json 格式化程序:

object Plan {
  implicit val planFormats = (
    (__ \ "id").format[String] and
    (__ \ "name").format[String] and
    (__ \ "apps").format[Int] and
    (__ \ "users").format[Int] and
    (__ \ "testruns").format[Int] and
    (__ \ "price").format[Int] and
    (__ \ "prio").format[Int]
  )(Plan.apply, unlift(Plan.unapply))
}
于 2013-05-06T07:20:42.143 回答