Scala 3 与使用 Enumeration 和 play-json 的 Scala 2 代码等效吗?

发布于 2025-01-14 16:39:52 字数 1594 浏览 3 评论 0 原文

我有一些可以在 Scala 2.{10,11,12,13} 中运行的代码,我现在正在尝试将其转换为 Scala 3。Scala 3 的枚举方式与 Scala 2 不同。我正在尝试弄清楚如何转换以下代码与 play-json 交互,以便它可以与 Scala 3 一起使用。对于已经跨过此桥的项目,有任何提示或代码提示吗?

// Scala 2.x style code in EnumUtils.scala 
import play.api.libs.json._
import scala.language.implicitConversions

// see: http://perevillega.com/enums-to-json-in-scala
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)
  }
}
// ----------------------------------------------------------------------------------
// Scala 2.x style code in Xyz.scala
import play.api.libs.json.{Reads, Writes}

object Xyz extends Enumeration {
  type Xyz = Value
  val name, link, unknown = Value
  implicit val enumReads: Reads[Xyz] = EnumUtils.enumReads(Xyz)
  implicit def enumWrites: Writes[Xyz] = EnumUtils.enumWrites
}

I have some code that works in Scala 2.{10,11,12,13} that I'm now trying to convert to Scala 3. Scala 3 does Enumeration differently than Scala 2. I'm trying to figure out how to convert the following code that interacts with play-json so that it will work with Scala 3. Any tips or pointers to code from projects that have already crossed this bridge?

// Scala 2.x style code in EnumUtils.scala 
import play.api.libs.json._
import scala.language.implicitConversions

// see: http://perevillega.com/enums-to-json-in-scala
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)
  }
}
// ----------------------------------------------------------------------------------
// Scala 2.x style code in Xyz.scala
import play.api.libs.json.{Reads, Writes}

object Xyz extends Enumeration {
  type Xyz = Value
  val name, link, unknown = Value
  implicit val enumReads: Reads[Xyz] = EnumUtils.enumReads(Xyz)
  implicit def enumWrites: Writes[Xyz] = EnumUtils.enumWrites
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄居者 2025-01-21 16:39:52

作为一个选项,您可以切换到 jsoniter-scala

它开箱即用地支持 Scala 2 和 Scala 3 的枚举。

它还可以方便地导出 safe高效 JSON 编解码器。

只需将所需的库添加到您的依赖项中:

libraryDependencies ++= Seq(
  // Use the %%% operator instead of %% for Scala.js and Scala Native 
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core"   % "2.13.5",
  // Use the "provided" scope instead when the "compile-internal" scope is not supported  
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.13.5" % "compile-internal"
)

然后派生一个编解码器并使用它:

import com.github.plokhotnyuk.jsoniter_scala.core._
import com.github.plokhotnyuk.jsoniter_scala.macros._

implicit val codec: JsonValueCodec[Xyz.Xyz] = JsonCodecMaker.make

println(readFromString[Xyz.Xyz]("\"name\""))

顺便说一句,您可以在 Scastie 上运行完整代码: https://scastie.scala-lang.org/Evj718q6TcCZow9lRhKaPw

As an option you can switch to jsoniter-scala.

It supports enums for Scala 2 and Scala 3 out of the box.

Also it has handy derivation of safe and efficient JSON codecs.

Just need to add required libraries to your dependencies:

libraryDependencies ++= Seq(
  // Use the %%% operator instead of %% for Scala.js and Scala Native 
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core"   % "2.13.5",
  // Use the "provided" scope instead when the "compile-internal" scope is not supported  
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "2.13.5" % "compile-internal"
)

And then derive a codec and use it:

import com.github.plokhotnyuk.jsoniter_scala.core._
import com.github.plokhotnyuk.jsoniter_scala.macros._

implicit val codec: JsonValueCodec[Xyz.Xyz] = JsonCodecMaker.make

println(readFromString[Xyz.Xyz]("\"name\""))

BTW, you can run the full code on Scastie: https://scastie.scala-lang.org/Evj718q6TcCZow9lRhKaPw

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文