gpt4 book ai didi

json - 为 Play Json 库中的单例提供隐式值

转载 作者:行者123 更新时间:2023-12-03 02:35:59 26 4
gpt4 key购买 nike

我有以下配置:

sealed trait Status
case object Edited extends Status
case object NotEdited extends Status

case class Tweet(content:String, status:Status)

我想使用 Play Json 格式,所以我想我必须有这样的东西(我不想在伴生对象中这样做):

trait JsonImpl{
implicit val TweetFormat = Json.format[Tweet]
implicit val statusFormat = Json.format[Status]
implicit val StatusFormat = Json.format[Edited.type]
implicit val NotEditedFormat = Json.format[NotEdited.type]
}

但是编译器提示并说:

没有可用的推文隐式格式。

它还说我无法使用 Edited.type 因为它需要 apply 和 unapply 函数。我该怎么办?

编辑1:

我可以想到这样的事情:

implicit object StatusFormat extends Format[Status] {
def reads(json: JsValue) =
(json \ "type").get.as[String] match {
case "" => Edited
case _ => UnEdited
}

def writes(stat: Status) = JsObject(Seq(
stat match {
case Edited => "type" -> JsString("Edited")
case NotEdited => "type" -> JsString("UnEdited")
}
))
}

但是read部分有问题,编译器提示它需要JsonResult而不是Edited.type

最佳答案

也可以使用函数式 API 非常干净地完成此操作:

import play.api.data.validation.ValidationError
import play.api.libs.functional.syntax._
import play.api.libs.json._

implicit val StatusFormat: Format[Status] = Format(
(__ \ 'type).read[String].collect[Status](ValidationError("Unknown status")) {
case "UnEdited" => NotEdited
case "Edited" => Edited
},
(__ \ 'type).write[String].contramap {
case Edited => "Edited"
case NotEdited => "UnEdited"
}
)

implicit val TweetFormat: Format[Tweet] = Json.format[Tweet]

我发现这比手动实现readswrites方法更清晰,主要是因为它强调了编码和解码之间的对称性。不过,这是一个品味问题。

关于json - 为 Play Json 库中的单例提供隐式值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30857815/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com