[英]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!
)
不幸的是, ModelSubclassA
和ModelSubclassB
都與其他案例類有多個關聯,盡管在編譯此示例時,當嘗試解析這些子類型時,它在運行時失敗。 總之,將有幾十個案例類構成返回數據的層次結構。
我也嘗試過使用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
子類編解碼器轉換為模棱兩可的隱式,這是有道理的。
啊...
答案需要兩部分:
“求和類型”封裝值和編解碼器與用於返回值的類型的距離。 在上面的示例中,編解碼器使用Model
特征來解析隱式。 如果也將其用作返回類型,則會引入遞歸定義,以使編譯器無法明確解析。
一旦使用了總和類型,客戶就很容易接受這些類型,並在match
使用提取器來獲取其中的實際值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.