2013-03-18 47 views
24

Play Framework 2.1中的新ScalaJson特性讓我有點失落。 我想在枚舉中寫入讀取和寫入。如何在Scala中讀取[T]和寫入[T]枚舉(播放框架2.1)

這裏是我的代碼:

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 
    } 
}} 

任何想法?

謝謝。

回答

41

簡短回答:使用類似Play Enumeration Utils的東西。

朗的答案,而不是把一個讀你的枚舉,你可以創建一個可重複使用的讀取爲枚舉類型:

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") 
    } 
    } 
} 

然後,當你想分析的東西的枚舉,創建隱式讀取您的特定Enum類型範圍:

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) 

你同樣可以使一個函數來創建一個格式對象結合讀取和寫入:

object EnumUtils { 
    .... 
    implicit def enumFormat[E <: Enumeration](enum: E): Format[E#Value] = { 
    Format(EnumReader.enumReads(enum), EnumWriter.enumWrites) 
    } 
} 
+0

當我嘗試在REPL我收到以下錯誤隱含VAL myEnumReads代碼:讀取[EnumA#值] = EnumUtils.enumReads(EnumA) 錯誤:未發現:類型EnumA 隱含VAL myEnumReads:讀取[EnumA #Value] = EnumUtils.enumReads(EnumA) ^ – smk 2013-03-25 01:19:47

+1

@smk:OPs上下文隱含在我發佈的代碼中。我已經更新了它現在包括在內。以下是完整的[作爲要點](https://gist.github.com/mikesname/5237809) – Mikesname 2013-03-25 15:13:44

+0

非常感謝。 – smk 2013-03-25 16:59:44

相關問題