web-dev-qa-db-ja.com

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)

私は何かが足りないのですか?

28
j3d

に変更してみてください

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

implicit val genderReads = Reads.enumNameReads(Gender)は正常に機能しています。再生Scala 2.4.2

29
surenyonjan

@surenyonjanの応答を拡張すると、以下はPlay Json2.6でうまく機能します。

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

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

より一般的で再利用可能なEnumerationReads、EnumerationWrites、およびEnumerationFormatクラスをまとめて、githubページに投稿しました。

EnumerationCombinators.scala

3
Rushing

2.7を再生

Play-json 2.7以降、 Json.formatEnum メソッド。 #14 のスコープに追加

例:

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)
}
1
Andrii Abramov