{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE StandaloneDeriving #-} -- | A module defining the KeyValuePairs type. This type may be used to -- represent a structure in a specification that is a collection of -- key-vaue pairs. For example query parameters and URLEncoded request -- bodies. -- -- The module provides FromJSON and ToJSON instances for KeyValuePairs. -- Valid KeyValuePairs JSON is a single JSON object where all values -- are either String, Scienfific or Bool. module Testing.CurlRunnings.Internal.KeyValuePairs ( KeyValuePairs (..) , KeyValuePair (..) ) where import Data.Aeson import Data.Aeson.Types import qualified Data.ByteString.Lazy as LBS import Data.List ((\\)) import qualified Data.Text as T import Data.Text.Encoding as T import qualified Testing.CurlRunnings.Internal.Aeson as A -- | A container for a list of key-value pairs newtype KeyValuePairs = KeyValuePairs [KeyValuePair] deriving Show -- | A representation of a single key-value pair data KeyValuePair = KeyValuePair A.KeyType T.Text deriving Show deriving instance Eq KeyValuePair -- KeyValuePairs should be considered equal if they contain the same elements. instance Eq KeyValuePairs where (==) (KeyValuePairs x) (KeyValuePairs y) = null (x \\ y) && null (y \\ x) instance ToJSON KeyValuePairs where toJSON (KeyValuePairs qs) = object (fmap (\(KeyValuePair k v) -> k .= toJSON v) qs) instance FromJSON KeyValuePairs where parseJSON = withObject "keyValuePairs" parseKeyValuePairs where parseKeyValuePairs o = KeyValuePairs <$> traverse parseKeyValuePair (A.toList o) parseKeyValuePair (k, v) = KeyValuePair k <$> parseSingleValueType v parseSingleValueType :: Value -> Parser T.Text parseSingleValueType (Bool b) = parseToText b parseSingleValueType (String t) = return t parseSingleValueType (Number n) = parseToText n parseSingleValueType invalid = typeMismatch "KeyValuePairs" invalid parseToText :: (ToJSON a) => a -> Parser T.Text parseToText = return . T.decodeUtf8 . LBS.toStrict . encode