Декодер JSON в вязе 0.18 - PullRequest
0 голосов
/ 28 июня 2018

В Elm 0.18 я хотел бы построить JSON-декодер для следующих примеров:

дело 1:

{"metadata": {"signatures":[{"metadata": {"code": "1234"}},
                            {"metadata": {"code": "5678"}}]}}  

-> { code = Just "1234" }

дело 2:

{"metadata": {"signatures":[]}} 

-> { code = Nothing }

дело 3:

{"metadata": {"signatures":[{"metadata": null}]}} 

-> { code = Nothing }

Это то, что я получил, но в случае 3 не получилось.

type alias Code = { code : Maybe String }

let
    js = """{"metadata": {"signatures":[{"metadata": {"code": "1234"}},
                   {"metadata": {"code": "5678"}}]}}"""

    dec1 =
        Decode.at [ "metadata", "code" ] Decode.string

    dec0 =
        Decode.list dec1
            |> Decode.andThen
                (\v ->
                    if List.isEmpty v then
                        Decode.succeed Nothing
                    else
                        Decode.succeed <| List.head v
                )

    dec =
        decode Code
            |> optionalAt [ "metadata", "signatures" ] dec0 Nothing

    expected =
        Ok { code = Just "1234" }
in
    Decode.decodeString dec js
        |> Expect.equal expected

Обходной путь - импортировать все данные в модель, а затем получить информацию из модели, но я предпочитаю избегать добавления ненужных данных в мою модель. Как я могу улучшить это?

1 Ответ

0 голосов
/ 28 июня 2018

Более упрощенный подход мог бы использовать Json.Decode.index для принудительного декодирования с нулевым индексом в виде строки, если она существует, в противном случае произойдет сбой, поэтому вы можете использовать Json.Decode.maybe для возврата Nothing в случае сбоя.

dec0 =
    Decode.maybe (Decode.index 0 dec1)
...