{-# OPTIONS_HADDOCK prune not-home #-}

{- |
Copyright   : (c) 2022 Tim Emiola
Maintainer  : Tim Emiola <adetokunbo@emio.la>
SPDX-License-Identifier: BSD3
-}
module KeyedVals.Handle.Codec.Aeson (
  -- * newtypes
  AesonOf (..),
) where

import Data.Aeson (
  FromJSON (..),
  ToJSON (..),
  eitherDecodeStrict',
  encode,
 )
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as Text
import KeyedVals.Handle.Codec (DecodeKV (..), EncodeKV (..))


{- | A deriving-via helper type for types that implement 'DecodeKV' and 'EncodeKV'
 using Aeson's 'FromJSON' and 'ToJSON' type classes.
-}
newtype AesonOf a = AesonOf {forall a. AesonOf a -> a
fromAesonOf :: a}


instance FromJSON a => DecodeKV (AesonOf a) where
  decodeKV :: Val -> Either Text (AesonOf a)
decodeKV = (String -> Either Text (AesonOf a))
-> (a -> Either Text (AesonOf a))
-> Either String a
-> Either Text (AesonOf a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Text -> Either Text (AesonOf a)
forall a b. a -> Either a b
Left (Text -> Either Text (AesonOf a))
-> (String -> Text) -> String -> Either Text (AesonOf a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack) (AesonOf a -> Either Text (AesonOf a)
forall a b. b -> Either a b
Right (AesonOf a -> Either Text (AesonOf a))
-> (a -> AesonOf a) -> a -> Either Text (AesonOf a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> AesonOf a
forall a. a -> AesonOf a
AesonOf) (Either String a -> Either Text (AesonOf a))
-> (Val -> Either String a) -> Val -> Either Text (AesonOf a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Either String a
forall a. FromJSON a => Val -> Either String a
eitherDecodeStrict'


instance ToJSON a => EncodeKV (AesonOf a) where
  encodeKV :: AesonOf a -> Val
encodeKV = ByteString -> Val
LBS.toStrict (ByteString -> Val)
-> (AesonOf a -> ByteString) -> AesonOf a -> Val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ByteString
forall a. ToJSON a => a -> ByteString
encode (a -> ByteString) -> (AesonOf a -> a) -> AesonOf a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AesonOf a -> a
forall a. AesonOf a -> a
fromAesonOf