2017-06-07 36 views
1

数组但对如何事情榆树解码另一个问题......解码JSON其中value可以是一个字符串或者不同的值

所以问题是,我需要解码的值可以是字符串,例如

"price_unknown"

,或者它可以是2个元素,其中第一个是一个字符串,所述第二阵列是一个浮动:

["price", 50.5]

而对于最终的价值我有一个类型:

type Something 
    = PriceUnknown 
    = Price Float 

到我需要的价值从JSON响应转换。

我试图用字里行间颇有几分的事情一大堆:

decode MyString 
    |> required "other_value" Json.Decode.string 
    |> required "price" JD.oneOf [JD.string, JD.list (JD.oneOf [JD.string, JD.float])] |> JD.map mapper 

(我在这里使用json_decode_pipeline包)

但很明显,它抱怨在列表和诸如此类的东西,以便对不同价值观我被卡住了。

预先感谢您。

回答

3

你很接近,但oneOf中的所有Decoder都必须具有相同的类型。另外,解构混合列表可能会很痛苦。这使用elm-community/json-extra来简化手动解码步骤。

myDecoder : Decoder SomethingElse 
myDecoder = 
    decode MyString 
     |> required "other_value" Json.Decode.string 
     |> required "price" priceDecoder 


priceDecoder : Decoder Something 
priceDecoder = 
    JD.oneOf 
     [ priceUnknownDecoder 
     , priceKnownDecoder 
     ] 


priceUnknownDecoder : Decoder Something 
priceUnknownDecoder = 
    JD.string 
     |> JD.andThen 
      (\string -> 
       if string == "price_unknown" then 
        JD.succeed PriceUnknown 
       else 
        JD.fail "Invalid unknown price string." 
      ) 


priceKnownDecoder : Decoder Something 
priceKnownDecoder = 
    listTupleDecoder 
     JD.string 
     JD.float 
     |> JD.andThen 
      (\(tag, price) -> 
       if tag == "price" then 
        JD.succeed (Price price) 
       else 
        JD.fail "Invalid tag string." 
      ) 


listTupleDecoder : Decoder a -> Decoder b -> Decoder (a, b) 
listTupleDecoder firstD secondD = 
    JD.list JD.value 
     |> JD.andThen 
      (\values -> 
       case values of 
        [first, second] -> 
         Result.map2 
          (,) 
          JD.decodeValue firstD first 
          JD.decodeValue secondD second 
          |> JD.Extra.fromResult 

        _ -> 
         JD.fail "There aren't two values in the list." 
      ) 
+0

我有一种感觉,它不会是一个班轮...... :)非常感谢 – JustMichael

相关问题