25

PlayFramework2.1の新しいScalaJson機能に少し迷いました。列挙型に読み取りと書き込みを書き込みたいのですが。

これが私のコードです:

object EnumA extends Enumeration {
 type EnumA = Value
 val VAL1, VAL2, VAL3 = Value

def parse(str:String) : EnumA = {
    str.toUpperCase() match {
         case "VAL1" => VAL1
         case "VAL2" => VAL2
         case "VAL3" => VAL3
         case _ => null
    }
}}

何か案が ?

ありがとう。

4

1 に答える 1

42

簡単な答え:PlayEnumerationUtilsのようなものを使用してください。

長い答えですが、列挙型に読み取りを入れる代わりに、列挙型の再利用可能な読み取りを作成できます。

object EnumA extends Enumeration {
  type EnumA = Value
  val VAL1, VAL2, VAL3 = Value
}

object EnumUtils {
  def enumReads[E <: Enumeration](enum: E): Reads[E#Value] = new Reads[E#Value] {
    def reads(json: JsValue): JsResult[E#Value] = json match {
      case JsString(s) => {
        try {
          JsSuccess(enum.withName(s))
        } catch {
          case _: NoSuchElementException => JsError(s"Enumeration expected of type: '${enum.getClass}', but it does not appear to contain the value: '$s'")
        }
      }
      case _ => JsError("String value expected")
    }
  }
}

次に、何かを列挙型に解析する場合は、スコープ内の特定の列挙型の暗黙的な読み取りを作成します。

import some.thing.EnumUtils
implicit val myEnumReads: Reads[EnumA.Value] = EnumUtils.enumReads(EnumA)

val myValue: EnumA.Value = someJsonObject.as[EnumA.Value]

また

val myValue: EnumA.Value = someJsonObject.asOpt[EnumA.Value].getOrElse(sys.error("Oh noes! Invalid value!"))

(Scalaでnullを使用するのは悪い形式と見なされます。)

JsValuesとして列挙型を記述する方が簡単です。

object EnumUtils {
  ...
  implicit def enumWrites[E <: Enumeration]: Writes[E#Value] = new Writes[E#Value] {
    def writes(v: E#Value): JsValue = JsString(v.toString)
  }
}

次に、列挙型を書き込もうとする前に、それをスコープにインポートします(または、toJson関数に明示的に渡します。

import EnumUtils.enumWrites
val myEnumJson: JsValue = Json.toJson(EnumA.VAL1)

同様に、読み取りと書き込みの両方を組み合わせたFormatオブジェクトを作成する関数を作成できます。

object EnumUtils {
  ....
  implicit def enumFormat[E <: Enumeration](enum: E): Format[E#Value] = {
    Format(EnumReader.enumReads(enum), EnumWriter.enumWrites)
  }
}
于 2013-03-18T23:59:30.507 に答える