diff --git a/elm.json b/elm.json index c0d3ecf..322c34d 100644 --- a/elm.json +++ b/elm.json @@ -11,6 +11,7 @@ "elm-version": "0.19.0 <= v < 0.20.0", "dependencies": { "elm/core": "1.0.0 <= v < 2.0.0", + "elm/json": "1.0.0 <= v < 2.0.0", "miniBill/elm-fast-dict": "1.0.0 <= v < 2.0.0" }, "test-dependencies": {} diff --git a/src/Internal/Tools/Iddict.elm b/src/Internal/Tools/Iddict.elm index 1f95deb..2a6b944 100644 --- a/src/Internal/Tools/Iddict.elm +++ b/src/Internal/Tools/Iddict.elm @@ -1,4 +1,4 @@ -module Internal.Tools.Iddict exposing (Iddict, empty, get, insert, isEmpty, keys, map, member, remove, singleton, size, values) +module Internal.Tools.Iddict exposing (Iddict, decoder, empty, encode, get, insert, isEmpty, keys, map, member, remove, singleton, size, values) {-| The id-dict is a data type that lets us store values in a dictionary using unique identifiers. This can be used as a dictionary where the keys do not matter. @@ -21,9 +21,15 @@ do not need to generate identifiers yourself. ## Lists @docs keys, values + +## JSON coders + +@docs encode, decoder -} import FastDict as Dict exposing (Dict) +import Json.Decode as D +import Json.Encode as E {-| The Iddict data type. -} @@ -33,6 +39,38 @@ type Iddict a , dict : Dict Int a } +{-| Decode an id-dict from a JSON value. +-} +decoder : D.Decoder a -> D.Decoder (Iddict a) +decoder xDecoder = + D.map2 + (\c pairs -> + let + dict : Dict Int a + dict = + pairs + |> List.filterMap + (\(k, v) -> + k + |> String.toInt + |> Maybe.map (\n -> (n, v)) + ) + |> Dict.fromList + in + Iddict + { cursor = + Dict.keys dict -- Larger than all values in the list + |> List.map ((+) 1) + |> List.maximum + |> Maybe.withDefault 0 + |> max (Dict.size dict) -- At least the dict size + |> max c -- At least the given value + , dict = dict + } + ) + (D.field "cursor" D.int) + (D.field "dict" <| D.keyValuePairs xDecoder) + {-| Create an empty id-dict. -} empty : Iddict a @@ -42,6 +80,19 @@ empty = , dict = Dict.empty } +{-| Encode an id-dict to a JSON value. +-} +encode : (a -> E.Value) -> Iddict a -> E.Value +encode encodeX (Iddict d) = + E.object + [ ( "cursor", E.int d.cursor ) + , ( "dict", + d.dict + |> Dict.toCoreDict + |> E.dict String.fromInt encodeX + ) + ] + {-| Get a value from the id-dict using its key. -} get : Int -> Iddict a -> Maybe a