{-# LANGUAGE TemplateHaskellQuotes #-}

module Argo.Type.Pair where

import qualified Argo.Decoder as Decoder
import qualified Argo.Literal as Literal
import qualified Control.DeepSeq as DeepSeq
import qualified Data.ByteString.Builder as Builder
import qualified Language.Haskell.TH.Syntax as TH

newtype Pair k v
    = Pair (k, v)
    deriving (Pair k v -> Pair k v -> Bool
(Pair k v -> Pair k v -> Bool)
-> (Pair k v -> Pair k v -> Bool) -> Eq (Pair k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. (Eq k, Eq v) => Pair k v -> Pair k v -> Bool
/= :: Pair k v -> Pair k v -> Bool
$c/= :: forall k v. (Eq k, Eq v) => Pair k v -> Pair k v -> Bool
== :: Pair k v -> Pair k v -> Bool
$c== :: forall k v. (Eq k, Eq v) => Pair k v -> Pair k v -> Bool
Eq, Int -> Pair k v -> ShowS
[Pair k v] -> ShowS
Pair k v -> String
(Int -> Pair k v -> ShowS)
-> (Pair k v -> String) -> ([Pair k v] -> ShowS) -> Show (Pair k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> Pair k v -> ShowS
forall k v. (Show k, Show v) => [Pair k v] -> ShowS
forall k v. (Show k, Show v) => Pair k v -> String
showList :: [Pair k v] -> ShowS
$cshowList :: forall k v. (Show k, Show v) => [Pair k v] -> ShowS
show :: Pair k v -> String
$cshow :: forall k v. (Show k, Show v) => Pair k v -> String
showsPrec :: Int -> Pair k v -> ShowS
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> Pair k v -> ShowS
Show)

instance (TH.Lift k, TH.Lift v) => TH.Lift (Pair k v) where
    liftTyped :: Pair k v -> Q (TExp (Pair k v))
liftTyped (Pair (k, v)
x) = [|| Pair x ||]

instance (DeepSeq.NFData k, DeepSeq.NFData v) => DeepSeq.NFData (Pair k v) where
    rnf :: Pair k v -> ()
rnf (Pair (k, v)
x) = (k, v) -> ()
forall a. NFData a => a -> ()
DeepSeq.rnf (k, v)
x

encode :: (k -> Builder.Builder) -> (v -> Builder.Builder) -> Pair k v -> Builder.Builder
encode :: (k -> Builder) -> (v -> Builder) -> Pair k v -> Builder
encode k -> Builder
f v -> Builder
g (Pair (k
x, v
y)) =
    k -> Builder
f k
x
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
Builder.word8 Word8
Literal.colon
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> v -> Builder
g v
y

decode :: Decoder.Decoder k -> Decoder.Decoder v -> Decoder.Decoder (Pair k v)
decode :: Decoder k -> Decoder v -> Decoder (Pair k v)
decode Decoder k
f Decoder v
g = do
    k
k <- Decoder k
f
    Word8 -> Decoder ()
Decoder.word8 Word8
Literal.colon
    Decoder ()
Decoder.spaces
    v
v <- Decoder v
g
    Pair k v -> Decoder (Pair k v)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pair k v -> Decoder (Pair k v)) -> Pair k v -> Decoder (Pair k v)
forall a b. (a -> b) -> a -> b
$ (k, v) -> Pair k v
forall k v. (k, v) -> Pair k v
Pair (k
k, v
v)