{-# LANGUAGE ConstrainedClassMethods #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Morpheus.Client.Fetch
( Fetch (..),
decodeResponse,
)
where
import Data.Aeson
( FromJSON,
ToJSON (..),
eitherDecode,
encode,
)
import Data.ByteString.Lazy (ByteString)
import Data.Morpheus.Client.Fetch.RequestType (Request (Request), RequestType (RequestArgs), processResponse, toRequest)
import Data.Morpheus.Client.Fetch.Types
( FetchError (..),
)
import Relude hiding (ByteString)
decodeResponse :: (FromJSON a) => ByteString -> Either (FetchError a) a
decodeResponse = (first FetchErrorParseFailure . eitherDecode) >=> processResponse
class (RequestType a, ToJSON (Args a), FromJSON a) => Fetch a where
type Args a :: Type
fetch :: (Monad m) => (ByteString -> m ByteString) -> Args a -> m (Either (FetchError a) a)
instance (RequestType a, ToJSON (Args a), FromJSON a) => Fetch a where
type Args a = RequestArgs a
fetch f args = decodeResponse <$> f (encode $ toRequest request)
where
request :: Request a
request = Request args