Parametrise over body contents only

This commit is contained in:
Oleg Grenrus 2019-02-05 11:51:42 +02:00
parent 9a655fd68e
commit 3a9a1ca55b
4 changed files with 50 additions and 21 deletions

View File

@ -58,6 +58,10 @@ library
, transformers >= 0.5.2.0 && < 0.6 , transformers >= 0.5.2.0 && < 0.6
, template-haskell >= 2.11.1.0 && < 2.15 , template-haskell >= 2.11.1.0 && < 2.15
if !impl(ghc >= 8.2)
build-depends:
bifunctors >= 5.5.3 && < 5.6
-- Servant dependencies -- Servant dependencies
build-depends: build-depends:
servant >= 0.15 && <0.16 servant >= 0.15 && <0.16

View File

@ -19,6 +19,12 @@ import Control.DeepSeq
(NFData (..)) (NFData (..))
import Control.Monad.Catch import Control.Monad.Catch
(Exception) (Exception)
import Data.Bifoldable
(Bifoldable (..))
import Data.Bifunctor
(Bifunctor (..))
import Data.Bitraversable
(Bitraversable (..), bifoldMapDefault, bimapDefault)
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as Builder import qualified Data.ByteString.Builder as Builder
import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy as LBS
@ -40,10 +46,10 @@ import Network.HTTP.Media
import Network.HTTP.Types import Network.HTTP.Types
(Header, HeaderName, HttpVersion (..), Method, QueryItem, (Header, HeaderName, HttpVersion (..), Method, QueryItem,
Status (..), http11, methodGet) Status (..), http11, methodGet)
import Servant.Client.Core.Internal.BaseUrl
(BaseUrl)
import Servant.API import Servant.API
(ToHttpApiData, toEncodedUrlPiece, toHeader) (ToHttpApiData, toEncodedUrlPiece, toHeader)
import Servant.Client.Core.Internal.BaseUrl
(BaseUrl)
-- | A type representing possible errors in a request -- | A type representing possible errors in a request
-- --
@ -83,24 +89,36 @@ mediaTypeRnf mt =
data RequestF body path = Request data RequestF body path = Request
{ requestPath :: path { requestPath :: path
, requestQueryString :: Seq.Seq QueryItem , requestQueryString :: Seq.Seq QueryItem
, requestBody :: body , requestBody :: Maybe (body, MediaType)
, requestAccept :: Seq.Seq MediaType , requestAccept :: Seq.Seq MediaType
, requestHeaders :: Seq.Seq Header , requestHeaders :: Seq.Seq Header
, requestHttpVersion :: HttpVersion , requestHttpVersion :: HttpVersion
, requestMethod :: Method , requestMethod :: Method
} deriving (Generic, Typeable, Eq, Show) } deriving (Generic, Typeable, Eq, Show, Functor, Foldable, Traversable)
instance Bifunctor RequestF where bimap = bimapDefault
instance Bifoldable RequestF where bifoldMap = bifoldMapDefault
instance Bitraversable RequestF where
bitraverse f g r = mk
<$> traverse (bitraverse f pure) (requestBody r)
<*> g (requestPath r)
where
mk b p = r { requestBody = b, requestPath = p }
instance (NFData path, NFData body) => NFData (RequestF body path) where instance (NFData path, NFData body) => NFData (RequestF body path) where
rnf r = rnf r =
rnf (requestPath r) rnf (requestPath r)
`seq` rnf (requestQueryString r) `seq` rnf (requestQueryString r)
`seq` rnf (requestBody r) `seq` rnfB (requestBody r)
`seq` rnf (fmap mediaTypeRnf (requestAccept r)) `seq` rnf (fmap mediaTypeRnf (requestAccept r))
`seq` rnf (requestHeaders r) `seq` rnf (requestHeaders r)
`seq` requestHttpVersion r `seq` requestHttpVersion r
`seq` rnf (requestMethod r) `seq` rnf (requestMethod r)
where
rnfB Nothing = ()
rnfB (Just (b, mt)) = rnf b `seq` mediaTypeRnf mt
type Request = RequestF (Maybe (RequestBody, MediaType)) Builder.Builder type Request = RequestF RequestBody Builder.Builder
-- | The request body. A replica of the @http-client@ @RequestBody@. -- | The request body. A replica of the @http-client@ @RequestBody@.
data RequestBody data RequestBody

View File

@ -55,6 +55,10 @@ library
, time >= 1.6.0.1 && < 1.9 , time >= 1.6.0.1 && < 1.9
, transformers >= 0.5.2.0 && < 0.6 , transformers >= 0.5.2.0 && < 0.6
if !impl(ghc >= 8.2)
build-depends:
bifunctors >= 5.5.3 && < 5.6
-- Servant dependencies. -- Servant dependencies.
-- Strict dependency on `servant-client-core` as we re-export things. -- Strict dependency on `servant-client-core` as we re-export things.
build-depends: build-depends:

View File

@ -31,6 +31,8 @@ import Control.Monad.STM
import Control.Monad.Trans.Control import Control.Monad.Trans.Control
(MonadBaseControl (..)) (MonadBaseControl (..))
import Control.Monad.Trans.Except import Control.Monad.Trans.Except
import Data.Bifunctor
(bimap)
import Data.ByteString.Builder import Data.ByteString.Builder
(toLazyByteString) (toLazyByteString)
import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString.Lazy as BSL
@ -196,9 +198,10 @@ performRequest req = do
fRes = Client.hrFinalResponse responses fRes = Client.hrFinalResponse responses
mkFailureResponse :: BaseUrl -> Request -> GenResponse BSL.ByteString -> ServantError mkFailureResponse :: BaseUrl -> Request -> GenResponse BSL.ByteString -> ServantError
mkFailureResponse burl request ourResponse = mkFailureResponse burl request =
FailureResponse (request {requestPath = (burl, path), requestBody = ()}) ourResponse FailureResponse (bimap (const ()) f request)
where path = BSL.toStrict $ toLazyByteString $ requestPath request where
f b = (burl, BSL.toStrict $ toLazyByteString b)
clientResponseToResponse :: Client.Response a -> GenResponse a clientResponseToResponse :: Client.Response a -> GenResponse a
clientResponseToResponse r = Response clientResponseToResponse r = Response