{-# OPTIONS_GHC -Wno-orphans #-}

-- |
-- Copyright: © 2022–2025 Jonathan Knowles
-- License: Apache-2.0
--
module Data.MonoidMap.JSON
    (
    -- * Introduction
    -- $_introduction

    -- * Examples
    -- $_examples

    -- * Laws
    -- $_laws
    )
    where

import Data.Aeson
    ( FromJSON (parseJSON)
    , FromJSONKey
    , ToJSON (toEncoding, toJSON)
    , ToJSONKey
    , decode
    , encode
    )
import Data.Bool
    ( Bool
    )
import Data.Eq
    ( Eq ((==))
    )
import Data.Functor
    ( Functor (fmap)
    )
import Data.Map.Strict
    ( Map
    )
import Data.Maybe
    ( Maybe
    )
import Data.Monoid
    ( Monoid (mempty)
    , Sum
    )
import Data.Monoid.Null
    ( MonoidNull
    )
import Data.MonoidMap
    ( MonoidMap
    , fromList
    , fromMap
    , toList
    , toMap
    )
import Data.Ord
    ( Ord
    )
import Prelude
    ( undefined
    , ($)
    , (.)
    )

-- $_introduction
-- #_introduction#
--
-- This module provides instances of 'ToJSON' and 'FromJSON' for 'MonoidMap'.
--
-- These instances provide objects of type 'MonoidMap' __@k@__ __@v@__ with a
-- JSON encoding that is /identical/ to objects of type 'Map' __@k@__ __@v@__,
-- which are serialised as either JSON /objects/ or /arrays/ depending on the
-- key type __@k@__.

-- $_examples
-- #_examples#
--
-- === Encoding as JSON objects
--
-- @
-- >>> 'encode' '$' 'MonoidMap'.'fromList' [("abc", 'Sum' 1), ("def", 'Sum' 2)]
--
-- "{\\"abc\\":1,\\"def\\":2}"
-- @
--
-- === Encoding as JSON arrays
--
-- @
-- >>> 'encode' '$' 'MonoidMap'.'fromList' [((1,2), 'Sum' 3), ((2,3), 'Sum' 5)]
--
-- "[[[1,2],3],[[2,3],5]]"
-- @

-- $_laws
-- #_laws#
--
-- === Encoding to JSON
--
-- The 'ToJSON' instance satisfies the following laws:
--
-- @
-- 'toEncoding' '==' 'toEncoding' '.' 'MonoidMap'.'toMap'
-- 'toJSON'     '==' 'toJSON'     '.' 'MonoidMap'.'toMap'
-- @
--
-- === Decoding from JSON
--
-- The 'FromJSON' instance satisfies the following law:
--
-- @
-- 'parseJSON' '==' 'fmap' ('fmap' 'MonoidMap'.'fromMap') 'parseJSON'
-- @
--
-- Mappings from keys to values that decode to 'mempty' are __not__ included in
-- decoded 'MonoidMap' objects.

_importsRequiredForDocumentation :: ()
_importsRequiredForDocumentation :: ()
_importsRequiredForDocumentation = ()
  where
    _Map :: Map () ()
    _Map :: Map () ()
_Map = Map () ()
forall a. HasCallStack => a
undefined

    _Sum :: Sum ()
    _Sum :: Sum ()
_Sum = Sum ()
forall a. HasCallStack => a
undefined

    _decodeEncode :: Maybe ()
    _decodeEncode :: Maybe ()
_decodeEncode = ByteString -> Maybe ()
forall a. FromJSON a => ByteString -> Maybe a
decode (ByteString -> Maybe ()) -> ByteString -> Maybe ()
forall a b. (a -> b) -> a -> b
$ () -> ByteString
forall a. ToJSON a => a -> ByteString
encode ()

    _equals :: () -> () -> Bool
    _equals :: () -> () -> Bool
_equals = () -> () -> Bool
forall a. Eq a => a -> a -> Bool
(==)

    _fromListToList :: [((), ())]
    _fromListToList :: [((), ())]
_fromListToList = MonoidMap () () -> [((), ())]
forall k v. MonoidMap k v -> [(k, v)]
toList (MonoidMap () () -> [((), ())]) -> MonoidMap () () -> [((), ())]
forall a b. (a -> b) -> a -> b
$ [((), ())] -> MonoidMap () ()
forall k v. (Ord k, MonoidNull v) => [(k, v)] -> MonoidMap k v
fromList []

    _mempty :: ()
    _mempty :: ()
_mempty = ()
forall a. Monoid a => a
mempty

instance
    ( ToJSONKey k
    , ToJSON v
    )
    => ToJSON (MonoidMap k v)
  where
    toEncoding :: MonoidMap k v -> Encoding
toEncoding = Map k v -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding (Map k v -> Encoding)
-> (MonoidMap k v -> Map k v) -> MonoidMap k v -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MonoidMap k v -> Map k v
forall k v. MonoidMap k v -> Map k v
toMap
    toJSON :: MonoidMap k v -> Value
toJSON = Map k v -> Value
forall a. ToJSON a => a -> Value
toJSON (Map k v -> Value)
-> (MonoidMap k v -> Map k v) -> MonoidMap k v -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MonoidMap k v -> Map k v
forall k v. MonoidMap k v -> Map k v
toMap

instance
    ( FromJSONKey k
    , Ord k
    , FromJSON v
    , MonoidNull v
    )
    => FromJSON (MonoidMap k v)
  where
    parseJSON :: Value -> Parser (MonoidMap k v)
parseJSON = (Parser (Map k v) -> Parser (MonoidMap k v))
-> (Value -> Parser (Map k v)) -> Value -> Parser (MonoidMap k v)
forall a b. (a -> b) -> (Value -> a) -> Value -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Map k v -> MonoidMap k v)
-> Parser (Map k v) -> Parser (MonoidMap k v)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Map k v -> MonoidMap k v
forall v k. MonoidNull v => Map k v -> MonoidMap k v
fromMap) Value -> Parser (Map k v)
forall a. FromJSON a => Value -> Parser a
parseJSON