/* Licensed under Apache-2.0 (C) All Contributors */
package io.github.dreamylost.other

import play.api.libs.json._

/**
 * 支持枚举与字符串的隐式转化
 *
 * @author 梦境迷离
 * @since 2019-11-23
 * @version v1.0
 */
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(EnumUtils.enumReads(enum), EnumUtils.enumWrites)
  }
}
