簡體   English   中英

使用Argonaut解析JSON流

[英]Parsing stream of JSON with Argonaut

我正在使用Argonaut來解析來自遠程JSON提供程序的對象。 該API有兩種類型的端點,一種是URL上的傳統REST請求,以及單個JSON對象的響應。 我可以在此類端點上使用Argonaut輕松解析復雜的JSON返回對象。

我的問題是提供程序的流終結點,該終結點從給定終結點的JSON受限集合中返回隨機JSON對象。 這些對象按照它們在站點上出現的順序返回,並且可以隨時返回大約二十種不同對象中的任何一個。

通過API,我找不到使用Argonaut處理此問題的方法。 這些API似乎都需要類型參數化,這在無法預測下一個對象的類型的環境中很難實現。 一種選擇是基於每個JSON塊中的前幾個字符來分派給不同的編解碼器,但這破壞了將JSON字符串發送到解析器並獲取對象作為回報的目標。

到目前為止,我能找到的最好的方法是讓所有頂級案例類都擴展一個空的trait

implicit def ModelDecodeJson: DecodeJson[Model] =
  DecodeJson(c =>
    c.as[ModelSubclassA].asInstanceOf[DecodeResult[Model]]
      ||| c.as[ModelSubclassB].asInstanceOf[DecodeResult[Model]]
      // many more here!
  )

不幸的是, ModelSubclassAModelSubclassB都與其他案例類有多個關聯,盡管在編譯此示例時,當嘗試解析這些子類型時,它在運行時失敗。 總之,將有幾十個案例類構成返回數據的層次結構。

我也嘗試過使用for理解來構建它,但是那里也沒有運氣。

有人可以在這里建議更好的模式嗎?

UPDATE

以下內容似乎具有更可擴展的模式,但是這些類型不配合使用:

implicit def ModelDecodeJson: DecodeJson[Model] =
  DecodeJson(c =>
    (c.as[ModelSubclassA] ||| c.as[ModelSubclassB]).asInstanceOf[DecodeResult[Model]]
  )

錯誤:(10,17)類型不匹配; 找到:argonaut.DecodeResult [ModelSubclassB]必需:argonaut.DecodeResult [Product with Serializable with Model]注意:ModelSubclassB <:Product with Serializable with Model,但是類DecodeResult在A類型中不變。您可能希望將A定義為+ A 。 (SLS 4.5)||| c.as [ModelSubclassB])。asInstanceOf [DecodeResult [Model]] ^

因此,我開始查看源代碼,並意識到DecodeResult的定義已更改為包含版本6.2-M1中的錯誤所建議的+A 不幸的是,升級到該版本會將所有Model子類編解碼器轉換為模棱兩可的隱式,這是有道理的。

啊...

答案需要兩部分:

  1. “求和類型”封裝值和編解碼器與用於返回值的類型的距離。 在上面的示例中,編解碼器使用Model特征來解析隱式。 如果也將其用作返回類型,則會引入遞歸定義,以使編譯器無法明確解析。

  2. 一旦使用了總和類型,客戶就很容易接受這些類型,並在match使用提取器來獲取其中的實際值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM