packages feed

req 0.3.1 → 0.4.0

raw patch · 4 files changed

+78/−11 lines, 4 filesdep +monad-controldep +transformers-base

Dependencies added: monad-control, transformers-base

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+## Req 0.4.0++* Added the `Req` monad and `runReq` function to run it. This allows to use+  `req` without defining new (orphan) instances.+ ## Req 0.3.1  * Added `basicAuthUnsafe`.
Network/HTTP/Req.hs view
@@ -95,6 +95,7 @@ {-# LANGUAGE FlexibleInstances          #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures             #-}+{-# LANGUAGE MultiParamTypeClasses      #-} {-# LANGUAGE OverloadedStrings          #-} {-# LANGUAGE RankNTypes                 #-} {-# LANGUAGE RecordWildCards            #-}@@ -123,6 +124,8 @@     -- $embedding-requests   , MonadHttp  (..)   , HttpConfig (..)+  , Req+  , runReq     -- * Request     -- ** Method     -- $method@@ -213,7 +216,10 @@ import Control.Arrow (first, second) import Control.Exception (Exception, try, handle, throwIO) import Control.Monad+import Control.Monad.Base import Control.Monad.IO.Class+import Control.Monad.Reader+import Control.Monad.Trans.Control import Control.Retry import Data.Aeson (ToJSON (..), FromJSON (..)) import Data.ByteString (ByteString)@@ -581,6 +587,42 @@     x { L.proxy                   = httpConfigProxy       , L.redirectCount           = httpConfigRedirectCount       , LI.requestManagerOverride = httpConfigAltManager }++-- | A monad that allows to run 'req' in any 'IO'-enabled monad without+-- having to define new instances.+--+-- @since 0.4.0++newtype Req a = Req (ReaderT HttpConfig IO a)+  deriving ( Functor+           , Applicative+           , Monad+           , MonadIO )++instance MonadBase IO Req where+  liftBase = liftIO++instance MonadBaseControl IO Req where+  type StM Req a = a+  liftBaseWith f = Req . ReaderT $ \r -> f (runReq r)+  {-# INLINEABLE liftBaseWith #-}+  restoreM       = Req . ReaderT . const . return+  {-# INLINEABLE restoreM #-}++instance MonadHttp Req where+  handleHttpException = Req . lift . throwIO+  getHttpConfig       = Req ask++-- | Run a computation in the 'Req' monad with the given 'HttpConfig'. In+-- case of exceptional situation an 'HttpException' will be thrown.+--+-- @since 0.4.0++runReq :: MonadIO m+  => HttpConfig        -- ^ 'HttpConfig' to use+  -> Req a             -- ^ Computation to run+  -> m a+runReq config (Req m) = liftIO (runReaderT m config)  ---------------------------------------------------------------------------- -- Request—Method
httpbin-tests/Network/HTTP/ReqSpec.hs view
@@ -9,8 +9,9 @@   ( spec ) where -import Control.Exception (throwIO)+import Control.Exception import Control.Monad.Reader+import Control.Monad.Trans.Control import Data.Aeson (Value (..), ToJSON (..), object, (.=)) import Data.Default.Class import Data.IORef@@ -41,17 +42,18 @@ spec :: Spec spec = do -  describe "exception throwing on non 2xx-status codes" $-    it "throws indeed for non-2xx" $ do-      let selector :: HttpException -> Bool-          selector (VanillaHttpException-                    (L.HttpExceptionRequest _-                     (L.StatusCodeException response chunk))) =-            L.responseStatus response == Y.status404 && not (B.null chunk)-          selector _ = False+  describe "exception throwing on non-2xx status codes" $+    it "throws indeed for non-2xx" $       req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty-        `shouldThrow` selector+        `shouldThrow` selector404 +  describe "exception throwing on non-2xx status codes (Req monad)" $+    it "throws indeed for non-2xx" $+      asIO . runReq def $+        liftBaseWith $ \run ->+          run (req GET (httpbin /: "foo") NoReqBody ignoreResponse mempty)+            `shouldThrow` selector404+   describe "response check via httpConfigCheckResponse" $     context "if it's set to always throw" $       it "throws indeed" $@@ -401,6 +403,15 @@         NoReqBody ignoreResponse mempty       responseStatusCode r `shouldBe` code +-- | Exception selector that selects only 404 “Not found” exceptions.++selector404 :: HttpException -> Bool+selector404 (VanillaHttpException+             (L.HttpExceptionRequest _+              (L.StatusCodeException response chunk))) =+  L.responseStatus response == Y.status404 && not (B.null chunk)+selector404 _ = False+ -- | Empty JSON 'Object'.  emptyObject :: Value@@ -410,3 +421,9 @@  reflectJSON :: ToJSON a => a -> Text reflectJSON = T.decodeUtf8 . BL.toStrict . A.encode++-- | Clarify to the type checker that the inner computation is in the 'IO'+-- monad.++asIO :: IO a -> IO a+asIO = id
req.cabal view
@@ -1,5 +1,5 @@ name:                 req-version:              0.3.1+version:              0.4.0 cabal-version:        >= 1.18 tested-with:          GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.1 license:              BSD3@@ -39,11 +39,13 @@                     , http-client      >= 0.5    && < 0.6                     , http-client-tls  >= 0.3.2  && < 0.4                     , http-types       >= 0.8    && < 10.0+                    , monad-control    >= 1.0    && < 1.1                     , mtl              >= 2.0    && < 3.0                     , retry            >= 0.7    && < 0.8                     , text             >= 0.2    && < 1.3                     , time             >= 1.2    && < 1.9                     , transformers     >= 0.4    && < 0.6+                    , transformers-base   if !impl(ghc >= 8.0)     build-depends:    semigroups   == 0.18.*   exposed-modules:    Network.HTTP.Req@@ -92,6 +94,7 @@                     , hspec            >= 2.0    && < 3.0                     , http-client      >= 0.5    && < 0.6                     , http-types       >= 0.8    && < 10.0+                    , monad-control    >= 1.0    && < 1.1                     , mtl              >= 2.0    && < 3.0                     , req                     , retry            >= 0.7    && < 0.8