2013-03-18 59 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

相关问题