Play Framework: как сериализовать/десериализировать перечисление в/из JSON

Учитывая следующее перечисление...

object MyEnum extends Enumeration {

  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val ValN = Value("valN")

  implicit val myEnumFormat = new Format[MyEnum] {
    def reads(json: JsValue) = MyEnum.withName(json.as[String].value) // doesn't compile
    def writes(myEnum: MyEnum) = JsString(myEnum.toString)
  }
}

... Мне нужно сериализовать/десериализовать его в/из JSON. myEnumFormat не компилируется, и я всегда получаю следующее сообщение об ошибке:

type mismatch;
[error]  found   : models.MyEnum.Value
[error]  required: play.api.libs.json.JsResult[models.MyEnumValue]
[error]  Note: implicit value myEnumFormat is not applicable here because it comes after the application point and it lacks an explicit result type
[error]     def reads(json: JsValue) = MyEnum.withName(json.as[JsString].value)

Я что-то пропустил?

Ответы

Ответ 1

Попробуйте изменить его на

def reads(json: JsValue) = JsSuccess(MyEnum.withName(json.as[String].value))

Ответ 2

implicit val genderReads = Reads.enumNameReads(Gender) работает отлично для меня. Воспроизвести Scala 2.4.2

Ответ 3

Расширяя ответ @surenyonjan, в Play Json 2.6 прекрасно работает следующее:

object MyEnum extends Enumeration {
  type MyEnum = Value
  val e1, e2 = Value

  implicit val myEnumReads = Reads.enumNameReads(MyEnum)
  implicit val myEnumWrites = Writes.enumNameWrites
}

Ответ 4

Я собрал более общие и повторно используемые классы EnumerationReads, EnumerationWrites и EnumerationFormat и разместил их на моей странице github:

EnumerationCombinators.scala

Ответ 5

Play 2.7

Начиная с play-json 2.7 существует метод Json.formatEnum. Добавлено в рамки # 140

Пример:

object MyEnum extends Enumeration {
  type MyEnum = Value

  val Val1 = Value("val1")
  val Val2 = Value("val2")
  val ValN = Value("valN")

  implicit val format = Json.formatEnum(this)
}