Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Example Play JSON Enum reading/writing

View gist:5237809
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
package enumtest
 
 
import play.api.libs.json._
 
 
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")
}
}
 
implicit def enumWrites[E <: Enumeration]: Writes[E#Value] = new Writes[E#Value] {
def writes(v: E#Value): JsValue = JsString(v.toString)
}
 
implicit def enumFormat[E <: Enumeration](enum: E): Format[E#Value] = {
Format(EnumReader.enumReads(enum), EnumWriter.enumWrites)
}
}
 
 
// Now let's test it
 
object EnumTest {
 
object EnumA extends Enumeration {
type EnumA = Value
val VAL1, VAL2, VAL3 = Value
}
 
implicit val enumAFormat = EnumUtils.enumFormat(EnumA)
val myEnumJson: JsValue = Json.toJson(EnumA.VAL1)
val myValue: EnumA.Value = myEnumJson.asOpt[EnumA.Value].getOrElse(sys.error("Oh noes! Invalid value!"))
 
def ok = EnumA.VAL1 == myValue
}

Hi

line 26: EnumReader is not defined. I removed it and the error was gone

when i use it like so:

object Status extends Enumeration {
    type Status = Value
    val Enabled, Disabled = Value
}

case class Product(id: Option[Long], ean: Long, name: String, description: String, status: Status = Status.Enabled)

implicit val productWrites = (
        (__ \ "id").write[Option[Long]] ~
        (__ \ "ean").write[Long] ~ 
        (__ \ "name").write[String] ~
        (__ \ "description").write[String] ~
        (__ \ "status").write[Status]
    )(unlift(Product.unapply))

    implicit val productReads = (
        (__ \ "id").readNullable[Long] ~
        (__ \ "ean").read[Long] ~ 
        (__ \ "name").read[String] ~
        (__ \ "description").read[String] ~
        (__ \ "status").read[Status]  
    )(Product)

the (__ \ "status").write[Status] works ok, but (__ \ "status").read[Status] gives an error "Description Resource Path Location Type
No Json formatter found for type models.Status.Status. Try to implement an implicit Format for this type"

why doesn't it work for "read"?

Thank you

In line 26 just change the EnumReader to EnumUtils. After that you should be able to write something like this:

implicit val enumTypeFormat = EnumUtils.enumFormat(EnumClass)

At least for me it works.

Thanks, worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.