enumeratum icon indicating copy to clipboard operation
enumeratum copied to clipboard

Play: Compatibility with JAVA_ENUM_STYLE

Open domdorn opened this issue 6 years ago • 1 comments

My frontend expects enums to be in the style of JAVA_ENUMS.

the current converters didn't do the trick for me, so I created this one:

import enumeratum.{Enum, EnumEntry}
import play.api.libs.json._

trait PlayFromToJavaEnum[A <: EnumEntry] { self: Enum[A] =>

  def entryNameToEnumName(in: String): String = {
    (in.charAt(0) + in.substring(1).replaceAll("([A-Z])", "_$1")).toUpperCase()
  }

  /*
   * Map of [[A]] object names to [[A]]s
   */
  lazy val nameLikeEnumToValueMap: Map[String, A] =
    values.map(v => entryNameToEnumName(v.entryName) -> v).toMap

  /**
    * Optionally returns an [[A]] for a given name assuming the value is upper case
    */
  def withNameLikeJavaEnumOnlyOption(name: String): Option[A] =
    nameLikeEnumToValueMap.get(name)

  def readsJavaEnumLikeOnly(enum: Enum[A]): Reads[A] = {
    case JsString(s) =>
      withNameLikeJavaEnumOnlyOption(s) match {
        case Some(obj) => JsSuccess(obj)
        case None      => JsError("error.expected.validenumvalue")
      }
    case _ => JsError("error.expected.enumstring")
  }

  def writesJavaEnumLikeOnly(enum: Enum[A]): Writes[A] = v => JsString(entryNameToEnumName(v.entryName))

  implicit val jsonFormat: Format[A] = Format(readsJavaEnumLikeOnly(self), writesJavaEnumLikeOnly(self))
}

Not sure this is worth to be included in the main distribution? or if u see issues with it? Would be happy about a discussion

domdorn avatar May 20 '19 21:05 domdorn

Hey there,

So this looks useful to me, but at the same time, I’m a bit weary of adding and maintaining these converters, since the ones that exist in Core have already proven hard to reason about and don’t please everyone.

As a result, I think I’d be more inclined to say no to this as-is.

lloydmeta avatar May 26 '19 06:05 lloydmeta