Skip to content

@mikesname /gist:5237809
Last active

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Example Play JSON Enum reading/writing
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
}
@mickeyvip

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

@fdz5

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.

@vega113

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.