我正在使用Scala和Circe。我有以下密封特质。
sealed trait Mode
case object Authentication extends Mode
case object Ocr extends Mode
调用此case object时,SessionModel.Authentication
的输出如下:
"Authentication":{}
我需要将这个转换为字符串,使其输出"authentication"
我正在使用Scala和Circe。我有以下密封特质。
sealed trait Mode
case object Authentication extends Mode
case object Ocr extends Mode
调用此case object时,SessionModel.Authentication
的输出如下:
"Authentication":{}
我需要将这个转换为字符串,使其输出"authentication"
正如Andriy Plokhotnyuk上面提到的那样,您可以使用circe-generic-extras:
import io.circe.Codec
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.semiauto.deriveEnumerationCodec
sealed trait Mode
case object Authentication extends Mode
case object Ocr extends Mode
object Mode {
private implicit val config: Configuration =
Configuration.default.copy(transformConstructorNames = _.toLowerCase)
implicit val modeCodec: Codec[Mode] = deriveEnumerationCodec[Mode]
}
然后:
scala> import io.circe.syntax._
import io.circe.syntax._
scala> (Authentication: Mode).asJson
res1: io.circe.Json = "authentication"
scala> io.circe.Decoder[Mode].decodeJson(res1)
res2: io.circe.Decoder.Result[Mode] = Right(Authentication)
(请注意,Codec
是0.12版中的新功能——对于早期版本,您必须像Andriy的评论中那样编写两个实例。)
不过,除非您需要维护很多这样的实例,我个人认为手动编写实例通常比使用circe-generic-extras更好,在这种情况下,手动编写实例甚至不会更加冗长:
import io.circe.{Decoder, Encoder}
sealed trait Mode
case object Authentication extends Mode
case object Ocr extends Mode
object Mode {
implicit val decodeMode: Decoder[Mode] = Decoder[String].emap {
case "authentication" => Right(Authentication)
case "ocr" => Right(Ocr)
case other => Left(s"Invalid mode: $other")
}
implicit val encodeMode: Encoder[Mode] = Encoder[String].contramap {
case Authentication => "authentication"
case Ocr => "ocr"
}
}
这个版本的工作原理与deriveEnumerationCodec
版本完全相同,但不需要任何东西,只需使用circe-core,更少神秘,编译速度更快等等。对于简单情况下具有直接映射的简单案例类,泛型衍生可以非常好用,但我认为人们经常试图将其扩展以涵盖所有情况,而手动编写实例并不会太麻烦,甚至可能更清晰明了。
sealed trait Mode extends Product with Serializable
,则可以使用更少的样板生成字符串:implicit val encodeMode: Encoder[Mode] = Encoder[String].contramap { _.productPrefix.toLowerCase }
- Sotomajor