Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Reads/Writes for Java Enum without Field

With the Play Framework's JSON library, how can I create a Reads and Writes for a Java enum without fields?

public enum EnumNoFields { RED, WHITE, BLUE }

implicit val EnumNoFieldsReads: Reads[EnumNoFields] = ?
implicit val EnumNoFieldsWrites: Writes[EnumNoFields] = ?
like image 435
Kevin Meredith Avatar asked Feb 12 '14 18:02

Kevin Meredith


2 Answers

I simply made use of Enum#name.

  implicit val EnumNoFieldsReads: Reads[EnumNoFields] =
    (JsPath \ "displayValue").read[String].map{x: String => EnumNoFields.valueOf(x)}

  implicit val EnumNoFieldsWrites: Writes[EnumNoFields] =
    (JsPath \ "displayValue").write[String].contramap{x:EnumNoFields => x.name}
like image 125
Kevin Meredith Avatar answered Sep 24 '22 07:09

Kevin Meredith


A generic solution would look like this:

def javaEnumFormat[E <: Enum[E] : ClassTag] = new Format[E] {
  override def reads(json: JsValue): JsResult[E] = json.validate[String] match {
    case JsSuccess(value, _) => try {
      val clazz = implicitly[ClassTag[E]].runtimeClass.asInstanceOf[Class[E]]
      JsSuccess(Enum.valueOf(clazz, value))
    } catch {
      case _: IllegalArgumentException => JsError("enumeration.unknown.value")
    }
    case JsError(_) => JsError("enumeration.expected.string")
  }

  override def writes(o: E): JsValue = JsString(o.toString)
}

which you can use like this:

implicit val enumNoFieldsFormat = javaEnumFormat[EnumNoFields]

like image 28
Marius Soutier Avatar answered Sep 26 '22 07:09

Marius Soutier