Elm JSON 带数据的 Union 类型的解码器
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
)
我的 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
)