Как декодировать поля объекта JSON в кортеж - PullRequest
1 голос
/ 05 мая 2020

Я сейчас изучаю Elm и застрял на декодировании JSON.

У меня есть структура, представляющая блоки:

type alias Properties a =
    { a
        | x : { v : Float, pos : Float }
        , y : { v : Float, pos : Float }
        , size : ( Float, Float )
        , el : Float
    }

type alias Pr =
    { v : Float, pos : Float }

type Block
    = Block BlockType BlockProp


type alias BlockProp =
    Properties { visibility : Int, tb : ( Float, Float ) }


type BlockType
    = Rock
    | Ground

И мне нужно декодировать блоки, сохраненные в JSON:

{
    "blocks": [{
            "type": "ground",
            "x": {
                "v": "0.0",
                "pos": "30"
            },
            "y": {
                "v": "0.0",
                "pos": "100.0"
            },
            "sizex": "50.0",
            "sizey": "70.0",
            "el": "1.0",
            "visibility": "1",
            "t": "20.0",
            "b": "30.0"
        },
        {
            "type": "rock",
            "x": {
                "v": "0.0",
                "pos": "30"
            },
            "y": {
                "v": "0.0",
                "pos": "100.0"
            },
            "sizex": "50.0",
            "sizey": "70.0",
            "el": "1.0",
            "visibility": "1",
            "t": "20.0",
            "b": "30.0"
        }
    ]
}

Может ли кто-нибудь помочь мне, как построить декодер для преобразования блоков, сохраненных в JSON, в type Block? :)

edit: Я пробовал что-то вроде этого:

blockDecoder : Decoder BlockProp
blockDecoder =
    map6 BlockProp
        (field "x"
            (map2 Pr
                (field "v" float)
                (field "pos" float)
            )
        )
        (field "y"
            (map2 Pr
                (field "v" float)
                (field "pos" float)
            )
        )
        (field "size" -- I DON'T KNOW HOW TO CONVERT sizex AND sizey TO TUPLE
        (field "el" float)
        (field "visibility" float)
        (field "tb" -- I DON'T KNOW HOW TO CONVERT t AND b TO TUPLE

У меня проблемы с преобразованием полей в кортежи ... Также я не знаю, как создать блок с правильный BlockType в зависимости от поля типа.

1 Ответ

3 голосов
/ 05 мая 2020

Вы можете создавать кортежи почти так же, как вы создаете записи, такие как Pr, просто заменяя конструктор записи на функцию построения пары Tuple.pair:

map2 Tuple.pair
    (field "sizex" float)
    (field "sizey" float)

Аналогично , чтобы получить тип блока, вам нужно декодировать type как String, а затем сопоставить результат этого с помощью функции, которая преобразует String s в BlockType s:

map stringToBlockType (field "type" string)
...