Parametrise over body contents only
This commit is contained in:
parent
9a655fd68e
commit
3a9a1ca55b
4 changed files with 50 additions and 21 deletions
|
@ -58,9 +58,13 @@ 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
|
||||||
|
|
||||||
-- Other dependencies: Lower bound around what is in the latest Stackage LTS.
|
-- Other dependencies: Lower bound around what is in the latest Stackage LTS.
|
||||||
-- Here can be exceptions if we really need features from the newer versions.
|
-- Here can be exceptions if we really need features from the newer versions.
|
||||||
|
|
|
@ -19,14 +19,20 @@ import Control.DeepSeq
|
||||||
(NFData (..))
|
(NFData (..))
|
||||||
import Control.Monad.Catch
|
import Control.Monad.Catch
|
||||||
(Exception)
|
(Exception)
|
||||||
import qualified Data.ByteString as BS
|
import Data.Bifoldable
|
||||||
import qualified Data.ByteString.Builder as Builder
|
(Bifoldable (..))
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import Data.Bifunctor
|
||||||
|
(Bifunctor (..))
|
||||||
|
import Data.Bitraversable
|
||||||
|
(Bitraversable (..), bifoldMapDefault, bimapDefault)
|
||||||
|
import qualified Data.ByteString as BS
|
||||||
|
import qualified Data.ByteString.Builder as Builder
|
||||||
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
import Data.Int
|
import Data.Int
|
||||||
(Int64)
|
(Int64)
|
||||||
import Data.Semigroup
|
import Data.Semigroup
|
||||||
((<>))
|
((<>))
|
||||||
import qualified Data.Sequence as Seq
|
import qualified Data.Sequence as Seq
|
||||||
import Data.Text
|
import Data.Text
|
||||||
(Text)
|
(Text)
|
||||||
import Data.Text.Encoding
|
import Data.Text.Encoding
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue