Enumeration自动推导找不到Encoder

问题描述 投票:0回答:2

我有这样一个案例类:

case class Admin(name: String, role: Role)

Role
是枚举

object Role extends Enumeration {
  type Role = Value
  val Manager = Value
}

当我尝试:

import io.circe.generic.auto._, io.circe.syntax._

val response = Admin("John", Role.Manager).asJson.noSpaces

我得到隐式编码器未找到错误。

not enough arguments for method asJson: (implicit encoder: io.circe.Encoder[Admin])io.circe.Json. Unspecified value parameter encoder.

我想这个错误是由于枚举,所以我改为:

trait Role

object Role {
  object Manager extends Role
}

但这也行不通

最后,我尝试了:

trait Role

object Manager extends Role

没有成功。有人能帮助我吗?谢谢!

scala enums circe
2个回答
2
投票

enumeratum-circe 启用以下语法

object CirceEnumeratumExample extends App {
  import enumeratum._
  import io.circe.generic.auto._, io.circe.syntax._

  sealed trait Role extends EnumEntry
  case object Role extends Enum[Role] with CirceEnum[Role] {
    case object Manager  extends Role
    case object User extends Role
    val values = findValues
  }

  case class Admin(name: String, role: Role)
  val response = Admin("John", Role.Manager).asJson.noSpaces
  println(response)
}

输出

{"name":"John","role":"Manager"}

在哪里

libraryDependencies += "com.beachape" %% "enumeratum" % "1.5.13",
libraryDependencies += "com.beachape" %% "enumeratum-circe" % "1.5.21"

0
投票

对于现在提出这个问题的任何人,您不必使用枚举,尽管它可能是您在大型代码库中的最佳选择。

正如this answer所解释的那样,circe支持开箱即用的枚举编码器的半自动推导。

我发现 circe——通过 circe-generics——也能够派生出抽象数据类型的编码器,但结果令人惊讶:

import io.circe.generic.auto._

sealed trait Role

object Role {
  case object Manager extends Role
  case object IC extends Role
}

Role.Manager.asJson.toString // "{}"

Employee("John", Role.Manager)
  .asJson
  .toString // "{"name": "John", "role": {"Manager": {}}}"

可以通过半自动推导快速为

Encoder
写一个
Role
实例。使用
Encoder[String]
召唤现有的编码器,然后将
Role
转换为
String

implicit val encoder: Encoder[Role] = 
  Encoder[String].contramap {
      case Manager => "Manager"
      case IC => "IC"
    }
© www.soinside.com 2019 - 2024. All rights reserved.