如何处理不同的JSON模式,并将hem分派给正确的解析器来处理?

如何处理不同的JSON模式,并将hem分派给正确的解析器来处理?,json,scala,circe,Json,Scala,Circe,我目前正在用Scala构建一个非常简单的JSON解析器,它必须处理两个(稍微不同的)模式。我的目标是解析json中的一个值,并基于该值,将其发送到相关解码器。我已经将circe用于我的实现,但也欢迎其他实现和/或建议 我已经为我的例子制定了一个简化版本来帮助澄清这个问题 我可以收到两种类型的JSON,一种是股票: "data": { "name": "XYZ" }, "type": "STOCK&q

我目前正在用Scala构建一个非常简单的JSON解析器,它必须处理两个(稍微不同的)模式。我的目标是解析json中的一个值,并基于该值,将其发送到相关解码器。我已经将circe用于我的实现,但也欢迎其他实现和/或建议

我已经为我的例子制定了一个简化版本来帮助澄清这个问题

我可以收到两种类型的JSON,一种是股票:

"data": {
  "name": "XYZ"
},
  "type": "STOCK"
}
或报价(与股票相似,但包含价格)

在我这方面,我开发了一个简单的解码器,看起来像这样(针对股票):

implicit private val dataDecoder:Decoder[Stock]=(hCursor:hCursor)=>{
为了{

isin我通常在需要序列化ADT时遇到这种情况。正如有人在对您的问题的评论中提到的,circe支持自动生成ADT编解码器,但我通常更喜欢手动编写编解码器

在任何情况下,在像您这样的情况下,我都会按照以下思路做一些事情:

sealed trait Data
case class StockData(name: String) extends Data
case class QuoteData(name: String, quote: Double) extends Data

implicit val stockDataEncoder: Encoder[StockData] = ???
implicit val stockDataDecoder: Decoder[StockData] = ???
implicit val quoteDataEncoder: Encoder[QuoteData] = ???
implicit val quoteDataDecoder: Decoder[QuoteData] = ???

implicit val dataEncoder: Encoder[Data] = Encoder.instance {
  case s: StockData => stockDataEncoder(s).withObject(_.add("type", "stock))
  case q: QuoteData => quoteDataEncoder(q).withObject(_.add("type", "quote"))
}

implicit val dataDecoder: Decoder[Data] = Decoder.instance { c =>
  for {
    stype <- c.get[String]("type)
    res <- stype match {
       case "stock" => stockDataDecoder(c)
       case "quote" => quoteDataDecoder(c)
       case unk => Left(DecodingFailure(s"Unsupported data type: ${unk}", c.history))
    }
  } yield res
}
密封特征数据
案例类StockData(名称:String)扩展数据
case类QuoteData(名称:String,quote:Double)扩展数据
隐式val stockDataEncoder:编码器[StockData]=???
隐式val stockDataDecoder:解码器[StockData]=???
隐式val QuoteData编码器:编码器[QuoteData]=???
隐式val QuoteData解码器:解码器[QuoteData]=???
隐式val dataEncoder:Encoder[Data]=Encoder.instance{
案例s:StockData=>stockDataEncoder.withObject(u.add(“type”,“stock))
案例q:QuoteData=>quoteDataEncoder(q).withObject(u.add(“type”,“quote”))
}
隐式val dataDecoder:Decoder[Data]=Decoder.instance{c=>
为了{
stype Circe可以对ADT进行解码/编码
implicit private val dataDecoder: Decoder[Stock] = (hCursor: HCursor) => {
    for {
      isin <- hCursor.downField("data").downField("name").as[String]
      typ <- hCursor.downField("type").as[StockType]
    } yield Instrument(name, typ, LocalDateTime.now())
  }
sealed trait Data
case class StockData(name: String) extends Data
case class QuoteData(name: String, quote: Double) extends Data

implicit val stockDataEncoder: Encoder[StockData] = ???
implicit val stockDataDecoder: Decoder[StockData] = ???
implicit val quoteDataEncoder: Encoder[QuoteData] = ???
implicit val quoteDataDecoder: Decoder[QuoteData] = ???

implicit val dataEncoder: Encoder[Data] = Encoder.instance {
  case s: StockData => stockDataEncoder(s).withObject(_.add("type", "stock))
  case q: QuoteData => quoteDataEncoder(q).withObject(_.add("type", "quote"))
}

implicit val dataDecoder: Decoder[Data] = Decoder.instance { c =>
  for {
    stype <- c.get[String]("type)
    res <- stype match {
       case "stock" => stockDataDecoder(c)
       case "quote" => quoteDataDecoder(c)
       case unk => Left(DecodingFailure(s"Unsupported data type: ${unk}", c.history))
    }
  } yield res
}