@@ -95,6 +95,7 @@
95{-# LANGUAGE FlexibleInstances #-}
95{-# LANGUAGE FlexibleInstances #-}
96{-# LANGUAGE GeneralizedNewtypeDeriving #-}
96{-# LANGUAGE GeneralizedNewtypeDeriving #-}
97{-# LANGUAGE KindSignatures #-}
97{-# LANGUAGE KindSignatures #-}
98+{-# LANGUAGE MultiParamTypeClasses #-}
98{-# LANGUAGE OverloadedStrings #-}
99{-# LANGUAGE OverloadedStrings #-}
99{-# LANGUAGE RankNTypes #-}
100{-# LANGUAGE RankNTypes #-}
100{-# LANGUAGE RecordWildCards #-}
101{-# LANGUAGE RecordWildCards #-}
@@ -123,6 +124,8 @@ module Network.HTTP.Req
123 -- $embedding-requests
124 -- $embedding-requests
124 , MonadHttp (..)
125 , MonadHttp (..)
125 , HttpConfig (..)
126 , HttpConfig (..)
126 -- * Request
129 -- * Request
127 -- ** Method
130 -- ** Method
128 -- $method
131 -- $method
@@ -213,7 +216,10 @@ import Control.Applicative
213import Control.Arrow (first, second)
216import Control.Arrow (first, second)
214import Control.Exception (Exception, try, handle, throwIO)
217import Control.Exception (Exception, try, handle, throwIO)
215import Control.Monad
218import Control.Monad
219+import Control.Monad.Base
216import Control.Monad.IO.Class
220import Control.Monad.IO.Class
221+import Control.Monad.Reader
222+import Control.Monad.Trans.Control
217import Control.Retry
223import Control.Retry
218import Data.Aeson (ToJSON (..), FromJSON (..))
224import Data.Aeson (ToJSON (..), FromJSON (..))
219import Data.ByteString (ByteString)
225import Data.ByteString (ByteString)
@@ -582,6 +588,42 @@ instance RequestComponent HttpConfig where
582 , L.redirectCount = httpConfigRedirectCount
588 , L.redirectCount = httpConfigRedirectCount
583 , LI.requestManagerOverride = httpConfigAltManager }
589 , LI.requestManagerOverride = httpConfigAltManager }
591+-- | A monad that allows to run 'req' in any 'IO'-enabled monad without
592+-- having to define new instances.
596+newtype Req a = Req (ReaderT HttpConfig IO a)
602+instance MonadBase IO Req where
605+instance MonadBaseControl IO Req where
607+ liftBaseWith f = Req . ReaderT $ \r -> f (runReq r)
608+ {-# INLINEABLE liftBaseWith #-}
609+ restoreM = Req . ReaderT . const . return
610+ {-# INLINEABLE restoreM #-}
612+instance MonadHttp Req where
613+ handleHttpException = Req . lift . throwIO
614+ getHttpConfig = Req ask
616+-- | Run a computation in the 'Req' monad with the given 'HttpConfig'. In
617+-- case of exceptional situation an 'HttpException' will be thrown.
622+ => HttpConfig -- ^ 'HttpConfig' to use
623+ -> Req a -- ^ Computation to run
625+runReq config (Req m) = liftIO (runReaderT m config)
585----------------------------------------------------------------------------
627----------------------------------------------------------------------------
586-- Request—Method
628-- Request—Method