lloydmeta / enumeratum

A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations.
MIT License
1.19k stars 149 forks source link

Play: Compatibility with JAVA_ENUM_STYLE #229

Open domdorn opened 5 years ago

domdorn commented 5 years ago

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

lloydmeta commented 5 years ago

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.