{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RecordWildCards #-}

-- | The "Client" module is the primary module you will need to import to perform HTTP requests with this library.
--
--  For a comprehensive documentation, please see: <https://dormouse.io/client.html>
module Dormouse.Client
  ( -- * Request / Response Types
    HttpRequest(..)
  , HttpResponse(..)
  -- * Request building
  , delete
  , get
  , Dormouse.Client.head
  , patch
  , post
  , put
  , supplyBody
  , accept
  , expectAs
  , expect
  , fetchAs
  , fetch
  -- * Dormouse Client Monad and Transformer
  , DormouseClientT
  , DormouseClient
  , runDormouseClientT
  , runDormouseClient
  -- * Dormouse Client Class
  , MonadDormouseClient(..)
  -- * Dormouse Client Config
  , C.newManager
  , TLS.tlsManagerSettings
  , HasDormouseClientConfig(..)
  , DormouseClientConfig(..)
  -- * Headers
  , HeaderName
  , HasHeaders(..)
  , HasMediaType(..)
  -- * Methods
  , HttpMethod(..)
  , AllowedBody
  , methodAsByteString
  -- * Payloads
  , RawRequestPayload(..)
  , RequestPayload(..)
  , ResponsePayload(..)
  , EmptyPayload
  , HtmlPayload
  , JsonPayload
  , UrlFormPayload
  , Empty
  , json
  , urlForm
  , noPayload
  , html
  -- * Exceptions
  , SomeDormouseException(..)
  , DecodingException(..)
  , MediaTypeException(..)
  , UnexpectedStatusCodeException(..)
  , UriException(..)
  , UrlException(..)
  -- * Uri
  , Uri
  , parseUri
  -- * Url
  , Url
  , AnyUrl(..)
  , IsUrl(..)
  , ensureHttp
  , ensureHttps
  , parseUrl
  , parseHttpUrl
  , parseHttpsUrl
  ) where

import Control.Exception.Safe (MonadThrow, throw)
import Control.Monad.IO.Class
import Control.Monad.Reader
import qualified Data.Map.Strict as Map
import qualified Data.ByteString as B
import Data.Proxy
import Dormouse.Client.Class
import Dormouse.Client.Data
import Dormouse.Client.Exception
import Dormouse.Client.Headers
import Dormouse.Client.Headers.MediaType
import Dormouse.Client.Payload
import Dormouse.Client.Methods
import Dormouse.Client.Status
import Dormouse.Client.Types
import Dormouse.Uri
import Dormouse.Url
import qualified Dormouse.Client.MonadIOImpl as IOImpl
import qualified Network.HTTP.Client as C
import qualified Network.HTTP.Client.TLS as TLS

-- | Create an HTTP request with the supplied URI and supplied method, containing no body and no headers
makeRequest :: IsUrl url => HttpMethod method -> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest :: HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod method
method url
url = HttpRequest :: forall url (method :: Symbol) body contentTag acceptTag.
HttpMethod method
-> url
-> Map HeaderName ByteString
-> body
-> HttpRequest url method body contentTag acceptTag
HttpRequest 
  { requestMethod :: HttpMethod method
requestMethod = HttpMethod method
method
  , requestUrl :: url
requestUrl = url
url
  , requestHeaders :: Map HeaderName ByteString
requestHeaders = Map HeaderName ByteString
forall k a. Map k a
Map.empty
  , requestBody :: Empty
requestBody = Empty
Empty
  }

-- | Create an HTTP DELETE request with the supplied URI, containing no body and no headers
delete :: IsUrl url => url -> HttpRequest url "DELETE" Empty EmptyPayload acceptTag
delete :: url -> HttpRequest url "DELETE" Empty EmptyPayload acceptTag
delete = HttpMethod "DELETE"
-> url -> HttpRequest url "DELETE" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "DELETE"
DELETE

-- | Create an HTTP GET request with the supplied URI, containing no body and no headers
get :: IsUrl url => url  -> HttpRequest url "GET" Empty EmptyPayload acceptTag
get :: url -> HttpRequest url "GET" Empty EmptyPayload acceptTag
get = HttpMethod "GET"
-> url -> HttpRequest url "GET" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "GET"
GET

-- | Create an HTTP HEAD request with the supplied URI, containing no body and no headers
head :: IsUrl url => url  -> HttpRequest url "HEAD" Empty EmptyPayload acceptTag
head :: url -> HttpRequest url "HEAD" Empty EmptyPayload acceptTag
head = HttpMethod "HEAD"
-> url -> HttpRequest url "HEAD" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "HEAD"
HEAD

-- | Create an HTTP PATCH request with the supplied URI, containing no body and no headers
patch :: IsUrl url => url  -> HttpRequest url "PATCH" Empty EmptyPayload acceptTag
patch :: url -> HttpRequest url "PATCH" Empty EmptyPayload acceptTag
patch = HttpMethod "PATCH"
-> url -> HttpRequest url "PATCH" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "PATCH"
PATCH

-- | Create an HTTP POST request with the supplied URI, containing no body and no headers
post :: IsUrl url => url  -> HttpRequest url "POST" Empty EmptyPayload acceptTag
post :: url -> HttpRequest url "POST" Empty EmptyPayload acceptTag
post = HttpMethod "POST"
-> url -> HttpRequest url "POST" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "POST"
POST

-- | Create an HTTP PUT request with the supplied URI, containing no body and no headers
put :: IsUrl url => url  -> HttpRequest url "PUT" Empty EmptyPayload acceptTag
put :: url -> HttpRequest url "PUT" Empty EmptyPayload acceptTag
put = HttpMethod "PUT"
-> url -> HttpRequest url "PUT" Empty EmptyPayload acceptTag
forall url (method :: Symbol) acceptTag.
IsUrl url =>
HttpMethod method
-> url -> HttpRequest url method Empty EmptyPayload acceptTag
makeRequest HttpMethod "PUT"
PUT

-- | Supply a body to an HTTP request using the supplied tag to indicate how the request should be encoded
supplyBody :: (AllowedBody method b, RequestPayload b contentTag) => Proxy contentTag -> b -> HttpRequest url method b' contentTag' acceptTag -> HttpRequest url method b contentTag acceptTag
supplyBody :: Proxy contentTag
-> b
-> HttpRequest url method b' contentTag' acceptTag
-> HttpRequest url method b contentTag acceptTag
supplyBody Proxy contentTag
prox b
b HttpRequest { requestHeaders :: forall url (method :: Symbol) body contentTag acceptTag.
HttpRequest url method body contentTag acceptTag
-> Map HeaderName ByteString
requestHeaders = Map HeaderName ByteString
headers, requestBody :: forall url (method :: Symbol) body contentTag acceptTag.
HttpRequest url method body contentTag acceptTag -> body
requestBody = b'
_, url
HttpMethod method
requestUrl :: url
requestMethod :: HttpMethod method
requestUrl :: forall url (method :: Symbol) body contentTag acceptTag.
HttpRequest url method body contentTag acceptTag -> url
requestMethod :: forall url (method :: Symbol) body contentTag acceptTag.
HttpRequest url method body contentTag acceptTag
-> HttpMethod method
..} =
  HttpRequest :: forall url (method :: Symbol) body contentTag acceptTag.
HttpMethod method
-> url
-> Map HeaderName ByteString
-> body
-> HttpRequest url method body contentTag acceptTag
HttpRequest 
    { requestHeaders :: Map HeaderName ByteString
requestHeaders = (ByteString -> Map HeaderName ByteString)
-> Maybe ByteString -> Map HeaderName ByteString
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\ByteString
v -> HeaderName
-> ByteString
-> Map HeaderName ByteString
-> Map HeaderName ByteString
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (HeaderName
"Content-Type" :: HeaderName) ByteString
v Map HeaderName ByteString
headers) (Maybe ByteString -> Map HeaderName ByteString)
-> (Maybe MediaType -> Maybe ByteString)
-> Maybe MediaType
-> Map HeaderName ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MediaType -> ByteString) -> Maybe MediaType -> Maybe ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MediaType -> ByteString
encodeMediaType (Maybe MediaType -> Map HeaderName ByteString)
-> Maybe MediaType -> Map HeaderName ByteString
forall a b. (a -> b) -> a -> b
$ Proxy contentTag -> Maybe MediaType
forall tag. HasMediaType tag => Proxy tag -> Maybe MediaType
mediaType Proxy contentTag
prox
    , requestBody :: b
requestBody = b
b
    , url
HttpMethod method
requestUrl :: url
requestMethod :: HttpMethod method
requestUrl :: url
requestMethod :: HttpMethod method
..
    }

-- | Supply a header to an HTTP request
supplyHeader :: (HeaderName, B.ByteString) -> HttpRequest url method b contentTag acceptTag -> HttpRequest url method b contentTag acceptTag
supplyHeader :: (HeaderName, ByteString)
-> HttpRequest url method b contentTag acceptTag
-> HttpRequest url method b contentTag acceptTag
supplyHeader (HeaderName
k, ByteString
v) HttpRequest url method b contentTag acceptTag
r = HttpRequest url method b contentTag acceptTag
r { requestHeaders :: Map HeaderName ByteString
requestHeaders = HeaderName
-> ByteString
-> Map HeaderName ByteString
-> Map HeaderName ByteString
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert HeaderName
k ByteString
v (Map HeaderName ByteString -> Map HeaderName ByteString)
-> Map HeaderName ByteString -> Map HeaderName ByteString
forall a b. (a -> b) -> a -> b
$ HttpRequest url method b contentTag acceptTag
-> Map HeaderName ByteString
forall url (method :: Symbol) body contentTag acceptTag.
HttpRequest url method body contentTag acceptTag
-> Map HeaderName ByteString
requestHeaders HttpRequest url method b contentTag acceptTag
r }

-- | Apply an accept header derived from the supplied tag proxy and add a type hint to the request, indicating how the response should be decodable
accept :: HasMediaType acceptTag => Proxy acceptTag -> HttpRequest url method b contentTag acceptTag -> HttpRequest url method b contentTag acceptTag
accept :: Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> HttpRequest url method b contentTag acceptTag
accept Proxy acceptTag
prox HttpRequest url method b contentTag acceptTag
r = HttpRequest url method b contentTag acceptTag
-> (ByteString -> HttpRequest url method b contentTag acceptTag)
-> Maybe ByteString
-> HttpRequest url method b contentTag acceptTag
forall b a. b -> (a -> b) -> Maybe a -> b
maybe HttpRequest url method b contentTag acceptTag
r (\ByteString
v -> (HeaderName, ByteString)
-> HttpRequest url method b contentTag acceptTag
-> HttpRequest url method b contentTag acceptTag
forall url (method :: Symbol) b contentTag acceptTag.
(HeaderName, ByteString)
-> HttpRequest url method b contentTag acceptTag
-> HttpRequest url method b contentTag acceptTag
supplyHeader (HeaderName
"Accept", ByteString
v) HttpRequest url method b contentTag acceptTag
r) (Maybe ByteString -> HttpRequest url method b contentTag acceptTag)
-> (Maybe MediaType -> Maybe ByteString)
-> Maybe MediaType
-> HttpRequest url method b contentTag acceptTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MediaType -> ByteString) -> Maybe MediaType -> Maybe ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MediaType -> ByteString
encodeMediaType (Maybe MediaType -> HttpRequest url method b contentTag acceptTag)
-> Maybe MediaType -> HttpRequest url method b contentTag acceptTag
forall a b. (a -> b) -> a -> b
$ Proxy acceptTag -> Maybe MediaType
forall tag. HasMediaType tag => Proxy tag -> Maybe MediaType
mediaType Proxy acceptTag
prox

-- | Make the supplied HTTP request, expecting a Successful (2xx) HTTP response with body type `b' to be delivered in some 'MonadDormouseClient m'
expect :: (MonadDormouseClient m, MonadThrow m, RequestPayload b contentTag, ResponsePayload b' acceptTag, IsUrl url) 
       => HttpRequest url method b contentTag acceptTag -> m (HttpResponse b')
expect :: HttpRequest url method b contentTag acceptTag
-> m (HttpResponse b')
expect HttpRequest url method b contentTag acceptTag
r = Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> m (HttpResponse b')
forall (m :: * -> *) b contentTag b' acceptTag url
       (method :: Symbol).
(MonadDormouseClient m, MonadThrow m, RequestPayload b contentTag,
 ResponsePayload b' acceptTag, IsUrl url) =>
Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> m (HttpResponse b')
expectAs (HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
forall url (method :: Symbol) b contentTag acceptTag.
HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
proxyOfReq HttpRequest url method b contentTag acceptTag
r) HttpRequest url method b contentTag acceptTag
r
  where 
    proxyOfReq :: HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
    proxyOfReq :: HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
proxyOfReq HttpRequest url method b contentTag acceptTag
_ = Proxy acceptTag
forall k (t :: k). Proxy t
Proxy

-- | Make the supplied HTTP request, expecting a Successful (2xx) HTTP response in the supplied format with body type `b' to be delivered in some 'MonadDormouseClient m'
expectAs :: (MonadDormouseClient m, MonadThrow m, RequestPayload b contentTag, ResponsePayload b' acceptTag, IsUrl url) 
         => Proxy acceptTag -> HttpRequest url method b contentTag acceptTag -> m (HttpResponse b')
expectAs :: Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> m (HttpResponse b')
expectAs Proxy acceptTag
tag HttpRequest url method b contentTag acceptTag
r = Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m (HttpResponse b'))
-> m (HttpResponse b')
forall (m :: * -> *) b contentTag b' acceptTag url
       (method :: Symbol) b''.
(MonadDormouseClient m, RequestPayload b contentTag,
 ResponsePayload b' acceptTag, IsUrl url) =>
Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m b'')
-> m b''
fetchAs Proxy acceptTag
tag HttpRequest url method b contentTag acceptTag
r HttpResponse b' -> m (HttpResponse b')
forall (m :: * -> *) body.
MonadThrow m =>
HttpResponse body -> m (HttpResponse body)
rejectNon2xx

-- | Make the supplied HTTP request and transform the response into a result in some 'MonadDormouseClient m'
fetch :: (MonadDormouseClient m, RequestPayload b contentTag, ResponsePayload b' acceptTag, IsUrl url) 
        => HttpRequest url method b contentTag acceptTag -> (HttpResponse b' -> m b'') -> m b''
fetch :: HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m b'') -> m b''
fetch HttpRequest url method b contentTag acceptTag
r = Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m b'')
-> m b''
forall (m :: * -> *) b contentTag b' acceptTag url
       (method :: Symbol) b''.
(MonadDormouseClient m, RequestPayload b contentTag,
 ResponsePayload b' acceptTag, IsUrl url) =>
Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m b'')
-> m b''
fetchAs (HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
forall url (method :: Symbol) b contentTag acceptTag.
HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
proxyOfReq HttpRequest url method b contentTag acceptTag
r) HttpRequest url method b contentTag acceptTag
r
  where  
    proxyOfReq :: HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
    proxyOfReq :: HttpRequest url method b contentTag acceptTag -> Proxy acceptTag
proxyOfReq HttpRequest url method b contentTag acceptTag
_ = Proxy acceptTag
forall k (t :: k). Proxy t
Proxy

-- | Make the supplied HTTP request and transform the response in the supplied format into a result in some 'MonadDormouseClient m'
fetchAs :: (MonadDormouseClient m, RequestPayload b contentTag, ResponsePayload b' acceptTag, IsUrl url) 
        => Proxy acceptTag -> HttpRequest url method b contentTag acceptTag -> (HttpResponse b' -> m b'') -> m b''
fetchAs :: Proxy acceptTag
-> HttpRequest url method b contentTag acceptTag
-> (HttpResponse b' -> m b'')
-> m b''
fetchAs Proxy acceptTag
tag HttpRequest url method b contentTag acceptTag
r HttpResponse b' -> m b''
f = do
  let r' :: HttpRequest url method RawRequestPayload contentTag acceptTag
r' = Proxy contentTag
-> HttpRequest url method b contentTag acceptTag
-> HttpRequest url method RawRequestPayload contentTag acceptTag
forall body contentTag url (method :: Symbol) acceptTag.
RequestPayload body contentTag =>
Proxy contentTag
-> HttpRequest url method body contentTag acceptTag
-> HttpRequest url method RawRequestPayload contentTag acceptTag
serialiseRequest (HttpRequest url method b contentTag acceptTag -> Proxy contentTag
forall url (method :: Symbol) b contentTag acceptTag.
HttpRequest url method b contentTag acceptTag -> Proxy contentTag
contentTypeProx HttpRequest url method b contentTag acceptTag
r) HttpRequest url method b contentTag acceptTag
r
  HttpResponse b'
resp <- HttpRequest url method RawRequestPayload contentTag acceptTag
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b'))
-> m (HttpResponse b')
forall (m :: * -> *) url (method :: Symbol) contentTag acceptTag b.
(MonadDormouseClient m, IsUrl url) =>
HttpRequest url method RawRequestPayload contentTag acceptTag
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b))
-> m (HttpResponse b)
send HttpRequest url method RawRequestPayload contentTag acceptTag
r' ((HttpResponse (SerialT IO Word8) -> IO (HttpResponse b'))
 -> m (HttpResponse b'))
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b'))
-> m (HttpResponse b')
forall a b. (a -> b) -> a -> b
$ Proxy acceptTag
-> HttpResponse (SerialT IO Word8) -> IO (HttpResponse b')
forall body tag.
ResponsePayload body tag =>
Proxy tag
-> HttpResponse (SerialT IO Word8) -> IO (HttpResponse body)
deserialiseRequest Proxy acceptTag
tag
  HttpResponse b' -> m b''
f HttpResponse b'
resp
  where  
    contentTypeProx :: HttpRequest url method b contentTag acceptTag -> Proxy contentTag
    contentTypeProx :: HttpRequest url method b contentTag acceptTag -> Proxy contentTag
contentTypeProx HttpRequest url method b contentTag acceptTag
_ = Proxy contentTag
forall k (t :: k). Proxy t
Proxy

rejectNon2xx :: MonadThrow m => HttpResponse body -> m (HttpResponse body)
rejectNon2xx :: HttpResponse body -> m (HttpResponse body)
rejectNon2xx HttpResponse body
r = case HttpResponse body -> Int
forall body. HttpResponse body -> Int
responseStatusCode HttpResponse body
r of
  Int
Successful -> HttpResponse body -> m (HttpResponse body)
forall (f :: * -> *) a. Applicative f => a -> f a
pure HttpResponse body
r
  Int
_          -> UnexpectedStatusCodeException -> m (HttpResponse body)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throw (UnexpectedStatusCodeException -> m (HttpResponse body))
-> UnexpectedStatusCodeException -> m (HttpResponse body)
forall a b. (a -> b) -> a -> b
$ Int -> UnexpectedStatusCodeException
UnexpectedStatusCodeException (HttpResponse body -> Int
forall body. HttpResponse body -> Int
responseStatusCode HttpResponse body
r)

-- | The DormouseClientT Monad Transformer
newtype DormouseClientT m a = DormouseClientT 
  { DormouseClientT m a -> ReaderT DormouseClientConfig m a
unDormouseClientT :: ReaderT DormouseClientConfig m a 
  } deriving (a -> DormouseClientT m b -> DormouseClientT m a
(a -> b) -> DormouseClientT m a -> DormouseClientT m b
(forall a b.
 (a -> b) -> DormouseClientT m a -> DormouseClientT m b)
-> (forall a b. a -> DormouseClientT m b -> DormouseClientT m a)
-> Functor (DormouseClientT m)
forall a b. a -> DormouseClientT m b -> DormouseClientT m a
forall a b. (a -> b) -> DormouseClientT m a -> DormouseClientT m b
forall (m :: * -> *) a b.
Functor m =>
a -> DormouseClientT m b -> DormouseClientT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> DormouseClientT m a -> DormouseClientT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> DormouseClientT m b -> DormouseClientT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> DormouseClientT m b -> DormouseClientT m a
fmap :: (a -> b) -> DormouseClientT m a -> DormouseClientT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> DormouseClientT m a -> DormouseClientT m b
Functor, Functor (DormouseClientT m)
a -> DormouseClientT m a
Functor (DormouseClientT m)
-> (forall a. a -> DormouseClientT m a)
-> (forall a b.
    DormouseClientT m (a -> b)
    -> DormouseClientT m a -> DormouseClientT m b)
-> (forall a b c.
    (a -> b -> c)
    -> DormouseClientT m a
    -> DormouseClientT m b
    -> DormouseClientT m c)
-> (forall a b.
    DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b)
-> (forall a b.
    DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a)
-> Applicative (DormouseClientT m)
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a
DormouseClientT m (a -> b)
-> DormouseClientT m a -> DormouseClientT m b
(a -> b -> c)
-> DormouseClientT m a
-> DormouseClientT m b
-> DormouseClientT m c
forall a. a -> DormouseClientT m a
forall a b.
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a
forall a b.
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
forall a b.
DormouseClientT m (a -> b)
-> DormouseClientT m a -> DormouseClientT m b
forall a b c.
(a -> b -> c)
-> DormouseClientT m a
-> DormouseClientT m b
-> DormouseClientT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (DormouseClientT m)
forall (m :: * -> *) a. Applicative m => a -> DormouseClientT m a
forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a
forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m (a -> b)
-> DormouseClientT m a -> DormouseClientT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> DormouseClientT m a
-> DormouseClientT m b
-> DormouseClientT m c
<* :: DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m a
*> :: DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
liftA2 :: (a -> b -> c)
-> DormouseClientT m a
-> DormouseClientT m b
-> DormouseClientT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> DormouseClientT m a
-> DormouseClientT m b
-> DormouseClientT m c
<*> :: DormouseClientT m (a -> b)
-> DormouseClientT m a -> DormouseClientT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
DormouseClientT m (a -> b)
-> DormouseClientT m a -> DormouseClientT m b
pure :: a -> DormouseClientT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> DormouseClientT m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (DormouseClientT m)
Applicative, Applicative (DormouseClientT m)
a -> DormouseClientT m a
Applicative (DormouseClientT m)
-> (forall a b.
    DormouseClientT m a
    -> (a -> DormouseClientT m b) -> DormouseClientT m b)
-> (forall a b.
    DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b)
-> (forall a. a -> DormouseClientT m a)
-> Monad (DormouseClientT m)
DormouseClientT m a
-> (a -> DormouseClientT m b) -> DormouseClientT m b
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
forall a. a -> DormouseClientT m a
forall a b.
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
forall a b.
DormouseClientT m a
-> (a -> DormouseClientT m b) -> DormouseClientT m b
forall (m :: * -> *). Monad m => Applicative (DormouseClientT m)
forall (m :: * -> *) a. Monad m => a -> DormouseClientT m a
forall (m :: * -> *) a b.
Monad m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
forall (m :: * -> *) a b.
Monad m =>
DormouseClientT m a
-> (a -> DormouseClientT m b) -> DormouseClientT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> DormouseClientT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> DormouseClientT m a
>> :: DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
DormouseClientT m a -> DormouseClientT m b -> DormouseClientT m b
>>= :: DormouseClientT m a
-> (a -> DormouseClientT m b) -> DormouseClientT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
DormouseClientT m a
-> (a -> DormouseClientT m b) -> DormouseClientT m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (DormouseClientT m)
Monad, MonadReader DormouseClientConfig, Monad (DormouseClientT m)
Monad (DormouseClientT m)
-> (forall a. IO a -> DormouseClientT m a)
-> MonadIO (DormouseClientT m)
IO a -> DormouseClientT m a
forall a. IO a -> DormouseClientT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (DormouseClientT m)
forall (m :: * -> *) a. MonadIO m => IO a -> DormouseClientT m a
liftIO :: IO a -> DormouseClientT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> DormouseClientT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (DormouseClientT m)
MonadIO, Monad (DormouseClientT m)
e -> DormouseClientT m a
Monad (DormouseClientT m)
-> (forall e a. Exception e => e -> DormouseClientT m a)
-> MonadThrow (DormouseClientT m)
forall e a. Exception e => e -> DormouseClientT m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (DormouseClientT m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> DormouseClientT m a
throwM :: e -> DormouseClientT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> DormouseClientT m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (DormouseClientT m)
MonadThrow, m a -> DormouseClientT m a
(forall (m :: * -> *) a. Monad m => m a -> DormouseClientT m a)
-> MonadTrans DormouseClientT
forall (m :: * -> *) a. Monad m => m a -> DormouseClientT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> DormouseClientT m a
$clift :: forall (m :: * -> *) a. Monad m => m a -> DormouseClientT m a
MonadTrans)

instance (MonadIO m, MonadThrow m) => MonadDormouseClient (DormouseClientT m) where
  send :: HttpRequest url method RawRequestPayload contentTag acceptTag
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b))
-> DormouseClientT m (HttpResponse b)
send = HttpRequest url method RawRequestPayload contentTag acceptTag
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b))
-> DormouseClientT m (HttpResponse b)
forall env (m :: * -> *) url (method :: Symbol) contentTag
       acceptTag b.
(HasDormouseClientConfig env, MonadReader env m, MonadIO m,
 IsUrl url) =>
HttpRequest url method RawRequestPayload contentTag acceptTag
-> (HttpResponse (SerialT IO Word8) -> IO (HttpResponse b))
-> m (HttpResponse b)
IOImpl.sendHttp

-- | A simple monad that allows you to run DormouseClient
type DormouseClient a = DormouseClientT IO a

-- | Run a 'DormouseClientT' using the supplied 'DormouseClientConfig' to generate a result in the underlying monad @m@
runDormouseClientT :: DormouseClientConfig -> DormouseClientT m a -> m a
runDormouseClientT :: DormouseClientConfig -> DormouseClientT m a -> m a
runDormouseClientT DormouseClientConfig
config DormouseClientT m a
dormouseClientT = ReaderT DormouseClientConfig m a -> DormouseClientConfig -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (DormouseClientT m a -> ReaderT DormouseClientConfig m a
forall (m :: * -> *) a.
DormouseClientT m a -> ReaderT DormouseClientConfig m a
unDormouseClientT DormouseClientT m a
dormouseClientT) DormouseClientConfig
config

-- | Run a 'DormouseClient' using the supplied 'DormouseClientConfig' to generate a result in 'IO'
runDormouseClient :: DormouseClientConfig -> DormouseClient a -> IO a
runDormouseClient :: DormouseClientConfig -> DormouseClient a -> IO a
runDormouseClient = DormouseClientConfig -> DormouseClient a -> IO a
forall (m :: * -> *) a.
DormouseClientConfig -> DormouseClientT m a -> m a
runDormouseClientT