module Data.HashMap.Strict.InsOrd.Autodocodec
  ( sortedElemsCodec,
    sortedElemsCodecWith,
  )
where

import Autodocodec (HasCodec (codec), JSONCodec, dimapCodec, listCodec)
import Data.HashMap.Strict.InsOrd (elems)
import Hasura.Prelude

-- | Codec for ordered hash maps where the key for each element can be inferred
-- from the element value. This codec serializes the hash map as an array sorted
-- by key.
sortedElemsCodec :: (HasCodec a, Hashable k, Ord k) => (a -> k) -> JSONCodec (InsOrdHashMap k a)
sortedElemsCodec :: (a -> k) -> JSONCodec (InsOrdHashMap k a)
sortedElemsCodec = JSONCodec a -> (a -> k) -> JSONCodec (InsOrdHashMap k a)
forall k a.
(Hashable k, Ord k) =>
JSONCodec a -> (a -> k) -> JSONCodec (InsOrdHashMap k a)
sortedElemsCodecWith JSONCodec a
forall value. HasCodec value => JSONCodec value
codec

-- | Codec for ordered hash maps where the key for each element can be inferred
-- from the element value. This codec serializes the hash map as an array sorted
-- by key.
--
-- This version is useful if there is no 'HasCodec' instance for the type of the
-- hash map values. You supply a codec as an argument instead.
sortedElemsCodecWith :: (Hashable k, Ord k) => JSONCodec a -> (a -> k) -> JSONCodec (InsOrdHashMap k a)
sortedElemsCodecWith :: JSONCodec a -> (a -> k) -> JSONCodec (InsOrdHashMap k a)
sortedElemsCodecWith JSONCodec a
valueCodec a -> k
keyForElem = ([a] -> InsOrdHashMap k a)
-> (InsOrdHashMap k a -> [a])
-> Codec Value [a] [a]
-> JSONCodec (InsOrdHashMap k a)
forall oldOutput newOutput newInput oldInput context.
(oldOutput -> newOutput)
-> (newInput -> oldInput)
-> Codec context oldInput oldOutput
-> Codec context newInput newOutput
dimapCodec [a] -> InsOrdHashMap k a
dec InsOrdHashMap k a -> [a]
enc (Codec Value [a] [a] -> JSONCodec (InsOrdHashMap k a))
-> Codec Value [a] [a] -> JSONCodec (InsOrdHashMap k a)
forall a b. (a -> b) -> a -> b
$ JSONCodec a -> Codec Value [a] [a]
forall input output.
ValueCodec input output -> ValueCodec [input] [output]
listCodec JSONCodec a
valueCodec
  where
    dec :: [a] -> InsOrdHashMap k a
dec = (a -> k) -> [a] -> InsOrdHashMap k a
forall k a.
(Eq k, Hashable k) =>
(a -> k) -> [a] -> InsOrdHashMap k a
oMapFromL a -> k
keyForElem
    enc :: InsOrdHashMap k a -> [a]
enc = (a -> k) -> [a] -> [a]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn a -> k
keyForElem ([a] -> [a])
-> (InsOrdHashMap k a -> [a]) -> InsOrdHashMap k a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsOrdHashMap k a -> [a]
forall k v. InsOrdHashMap k v -> [v]
elems