3
votes

This question is related to the following two questions.

We wanted to use enumeration in a model in our play 2.1 application so we found the following question How to write Reads[T] and Writes[T] in scala Enumeration (play framework 2.1)

It's then mentioned that using case class in scala is better than scala enumeration. So we found the following question

Case objects vs Enumerations in Scala

How do we write json format for the case class enumeration suggested above then? Namely the case class enumeration is like

trait Enum[A] {
  trait Value { self: A => }
  val values: List[A]
}

sealed trait Currency extends Currency.Value
object Currency extends Enum[Currency] {
  case object EUR extends Currency
  case object GBP extends Currency
  val values = List(EUR, GBP)
}

We are new to Play/scala especially its functional JSON api. I tried to write Thanks

1

1 Answers

-1
votes

Other implementation

object EnumFormat {
  implicit def jsonReads[A](enum: Enumeration): Reads[A] = new Reads[A] {
    def reads(json: JsValue): JsResult[A] = json match {
      case JsString(s) => {
        try {
          JsSuccess(enum.withName(s).asInstanceOf[A])
        } catch {
          case _: NoSuchElementException =>
            JsError(s"Enumeration expected of type: '${enum.getClass}', but it does not contain '$s'")
        }
      }
      case _ => JsError("String value expected")
    }
  }
  implicit def jsonWrites[A]: Writes[A] = new Writes[A] {
    def writes(v: A): JsValue = JsString(v.toString)
  }
  implicit def jsonFormat[A](enum: Enumeration): Format[A] = {
    Format(jsonReads(enum), jsonWrites)
  }
}

object DeviceStatus extends Enumeration {

  val UNKNOWN = DeviceStatusType(0x0)
  val REGISTERED = DeviceStatusType(0x1)
  val NO_REGISTERED = DeviceStatusType(0x1000)

  case class DeviceStatusType(code: Int) extends Val(code) {

    import play.api.libs.json._
    import play.api.libs.functional.syntax._

    implicit def valueTo(v: Value): DeviceStatusType = v.asInstanceOf[DeviceStatusType]
  }

  implicit val jsonFormat: Format[DeviceStatus.DeviceStatusType] = EnumFormat.jsonFormat(DeviceStatus)
}