gpt4 book ai didi

json - Scala,喷雾-json : universal enumeration json formatting

转载 作者:行者123 更新时间:2023-12-04 13:57:00 31 4
gpt4 key购买 nike

我有这样的模型:两个枚举和一个具有这些枚举类型的两个字段的案例类:

// see later, why objects are implicit
implicit object Fruits extends Enumeration {
val Apple = Value("apple")
val Orange = Value("orange")
}

implicit object Vegetables extends Enumeration {
val Potato = Value("potato")
val Cucumber = Value("cucumber")
val Tomato = Value("tomato")
}

type Fruit = Fruits.Value
type Vegetable = Vegetables.Value

case class Pair(fruit: Fruit, vegetable: Vegetable)

我想用spray-json解析/生成JSON到/从Pairs。我不想单独声明 JsonFormat s 用于水果和蔬菜。所以,我想做这样的事情:
import spray.json._
import spray.json.DefaultJsonProtocol._

// enum is implicit here, that's why we needed implicit objects
implicit def enumFormat[A <: Enumeration](implicit enum: A): RootJsonFormat[enum.Value] =
new RootJsonFormat[enum.Value] {
def read(value: JsValue): enum.Value = value match {
case JsString(s) =>
enum.withName(s)
case x =>
deserializationError("Expected JsString, but got " + x)
}

def write(obj: enum.Value) = JsString(obj.toString)
}

// compilation error: couldn't find implicits for JF[Fruit] and JF[Vegetable]
implicit val pairFormat = jsonFormat2(Pair)

// expected value:
// spray.json.JsValue = {"fruit":"apple","vegetable":"potato"}
// but actually doesn't even compile
Pair(Fruits.Apple, Vegetables.Potato).toJson

遗憾的是, enumFormat不会为 jsonFormat2 产生隐式值.如果我在水果和蔬菜格式的 pairFormat 之前手动编写两个隐式声明,那么 json 编码工作:
implicit val fruitFormat: RootJsonFormat[Fruit] = enumFormat(Fruits)
implicit val vegetableFormat: RootJsonFormat[Vegetable] = enumFormat(Vegetables)

implicit val pairFormat = jsonFormat2(Pair)

// {"fruit":"apple","vegetable":"potato"}, as expected
Pair(Fruits.Apple, Vegetables.Potato).toJson

所以,两个问题:
  • 如何摆脱这些 fruitFormatvegetableFormat声明?
  • 理想情况下,最好不要隐式枚举对象,同时保持 enumFormat功能通用。有没有办法实现这一目标?也许,使用 scala.reflect包或类似的东西。
  • 最佳答案

    你只需要更换 enum.ValueA#Value .

    看着 spray-json #200您可以找到定义明确的隐式 enumFormat 的示例,稍微修改以利用隐式 enu恢复:

    implicit def enumFormat[T <: Enumeration](implicit enu: T): RootJsonFormat[T#Value] =
    new RootJsonFormat[T#Value] {
    def write(obj: T#Value): JsValue = JsString(obj.toString)
    def read(json: JsValue): T#Value = {
    json match {
    case JsString(txt) => enu.withName(txt)
    case somethingElse => throw DeserializationException(s"Expected a value from enum $enu instead of $somethingElse")
    }
    }
    }

    关于json - Scala,喷雾-json : universal enumeration json formatting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46612186/

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