簡體   English   中英

帶有數據的 Union 類型的 Elm JSON 解碼器

[英]Elm JSON decoder for Union type with data

我的 json 看起來像這樣:

{"name": "providerWithVal", "value": "example"}

或者像這樣:

{"name": "provider2"}

要么

{"name": "provider3"}

我的 Elm 聯合類型定義如下:

type Provider
    = ProviderWithVal String
    | Provider2
    | Provider3

我可以為沒有附加數據的聯合類型編寫解碼器。 但是ProviderWithVal需要一個字符串,我不確定如何讓它全部工作。

這是我到目前為止所擁有的:

import Json.Decode as D

providerDecoder : D.Decoder Provider
providerDecoder =
    D.field "name" D.string |> D.andThen providerNameDecoder

providerNameDecoder : String -> D.Decoder Provider
providerNameDecoder string =
    case string of
        "providerWithVal" -> D.succeed ProviderWithVal
        "provider2" -> D.succeed Provider2
        "provider3" -> D.succeed Provider3
        _ -> D.fail <| "Invalid provider: " ++ string

您問題的快速解決方案是將D.succeed ProviderWithVal替換為D.map ProviderWithVal (D.field "value" Decode.string)

但我會創建一個幫助器來匹配目標字符串,然后按以下方式使用它:

decoder =
    Decode.oneOf [ decodeWithVal, decodeP2, decodeP3 ]


decodeWithVal =
    exactMatch (Decode.field "name" Decode.string)
        "providerWithVal"
        (Decode.map ProviderWithVal <| Decode.field "value" Decode.string)


decodeP2 =
    exactMatch (Decode.field "name" Decode.string) "provider2" (Decode.succeed Provider2)


decodeP3 =
    exactMatch (Decode.field "name" Decode.string) "provider3" (Decode.succeed Provider3)


exactMatch : Decoder String -> String -> Decoder a -> Decoder a
exactMatch matchDecoder match dec =
    matchDecoder
        |> Decode.andThen
            (\str ->
                if str == match then
                    dec

                else
                    Decode.fail <| "[exactMatch] tgt: " ++ match ++ " /= " ++ str
            )

暫無
暫無

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

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