{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Network.HTTP.ApiMaker.Class
( Request(..)
, Config (..)
, SessionState (..)
, Session(..)
, emptySession
, runSafeReqM
, askConfig
, askApiConfig
, SafeReqSt
, SafeReq
, SafeReqM (..)
) where
import Control.Monad.Base
import Control.Monad.Except
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State
import Data.Kind (Type)
import Data.Proxy
import Network.HTTP.Req
import Network.HTTP.ApiMaker.SessionState
class (HttpMethod (Method r), HttpBody (Body r), HttpResponse (Response r), HttpBodyAllowed (AllowsBody (Method r)) (ProvidesBody (Body r))) =>
Request cfg r
where
type Method r :: Type
type Body r :: Type
type Response r :: Type
type Output r :: Type
method :: cfg -> r -> Method r
url :: cfg -> r -> Url 'Https
body :: cfg -> r -> Body r
response :: cfg -> r -> Proxy (Response r)
option :: cfg -> r -> Option 'Https
process :: (MonadHttp m, SessionState st) => cfg -> r -> Response r -> StateT st m (Output r)
data Config cfg = Config
{ Config cfg -> HttpConfig
httpConfig :: HttpConfig
, Config cfg -> [Option 'Https]
apiDefaultParameters :: [Option 'Https]
, Config cfg -> cfg
apiConfig :: cfg
}
type SafeReqSt sessionState cfg a = StateT sessionState (SafeReqM cfg) a
type SafeReq cfg a = SafeReqSt Session cfg a
newtype SafeReqM cfg a =
SafeReqM (ExceptT HttpException (ReaderT (Config cfg) IO) a)
deriving (a -> SafeReqM cfg b -> SafeReqM cfg a
(a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
(forall a b. (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b)
-> (forall a b. a -> SafeReqM cfg b -> SafeReqM cfg a)
-> Functor (SafeReqM cfg)
forall a b. a -> SafeReqM cfg b -> SafeReqM cfg a
forall a b. (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
forall cfg a b. a -> SafeReqM cfg b -> SafeReqM cfg a
forall cfg a b. (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SafeReqM cfg b -> SafeReqM cfg a
$c<$ :: forall cfg a b. a -> SafeReqM cfg b -> SafeReqM cfg a
fmap :: (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
$cfmap :: forall cfg a b. (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
Functor, Functor (SafeReqM cfg)
a -> SafeReqM cfg a
Functor (SafeReqM cfg)
-> (forall a. a -> SafeReqM cfg a)
-> (forall a b.
SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b)
-> (forall a b c.
(a -> b -> c)
-> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c)
-> (forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b)
-> (forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a)
-> Applicative (SafeReqM cfg)
SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a
SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
(a -> b -> c) -> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c
forall cfg. Functor (SafeReqM cfg)
forall a. a -> SafeReqM cfg a
forall cfg a. a -> SafeReqM cfg a
forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a
forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
forall a b.
SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a
forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
forall cfg a b.
SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
forall a b c.
(a -> b -> c) -> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c
forall cfg a b c.
(a -> b -> c) -> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c
forall (f :: Type -> Type).
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
<* :: SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a
$c<* :: forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg a
*> :: SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
$c*> :: forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
liftA2 :: (a -> b -> c) -> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c
$cliftA2 :: forall cfg a b c.
(a -> b -> c) -> SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg c
<*> :: SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
$c<*> :: forall cfg a b.
SafeReqM cfg (a -> b) -> SafeReqM cfg a -> SafeReqM cfg b
pure :: a -> SafeReqM cfg a
$cpure :: forall cfg a. a -> SafeReqM cfg a
$cp1Applicative :: forall cfg. Functor (SafeReqM cfg)
Applicative, Applicative (SafeReqM cfg)
a -> SafeReqM cfg a
Applicative (SafeReqM cfg)
-> (forall a b.
SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b)
-> (forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b)
-> (forall a. a -> SafeReqM cfg a)
-> Monad (SafeReqM cfg)
SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b
SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
forall cfg. Applicative (SafeReqM cfg)
forall a. a -> SafeReqM cfg a
forall cfg a. a -> SafeReqM cfg a
forall a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
forall a b.
SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b
forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
forall cfg a b.
SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b
forall (m :: Type -> Type).
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 -> SafeReqM cfg a
$creturn :: forall cfg a. a -> SafeReqM cfg a
>> :: SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
$c>> :: forall cfg a b. SafeReqM cfg a -> SafeReqM cfg b -> SafeReqM cfg b
>>= :: SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b
$c>>= :: forall cfg a b.
SafeReqM cfg a -> (a -> SafeReqM cfg b) -> SafeReqM cfg b
$cp1Monad :: forall cfg. Applicative (SafeReqM cfg)
Monad, Monad (SafeReqM cfg)
Monad (SafeReqM cfg)
-> (forall a. IO a -> SafeReqM cfg a) -> MonadIO (SafeReqM cfg)
IO a -> SafeReqM cfg a
forall cfg. Monad (SafeReqM cfg)
forall a. IO a -> SafeReqM cfg a
forall cfg a. IO a -> SafeReqM cfg a
forall (m :: Type -> Type).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> SafeReqM cfg a
$cliftIO :: forall cfg a. IO a -> SafeReqM cfg a
$cp1MonadIO :: forall cfg. Monad (SafeReqM cfg)
MonadIO)
askConfig :: SafeReqM cfg (Config cfg)
askConfig :: SafeReqM cfg (Config cfg)
askConfig = ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
-> SafeReqM cfg (Config cfg)
forall cfg a.
ExceptT HttpException (ReaderT (Config cfg) IO) a -> SafeReqM cfg a
SafeReqM (ReaderT (Config cfg) IO (Config cfg)
-> ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT (Config cfg) IO (Config cfg)
forall (m :: Type -> Type) r. Monad m => ReaderT r m r
ask)
askApiConfig :: SafeReqM cfg cfg
askApiConfig :: SafeReqM cfg cfg
askApiConfig = Config cfg -> cfg
forall cfg. Config cfg -> cfg
apiConfig (Config cfg -> cfg)
-> SafeReqM cfg (Config cfg) -> SafeReqM cfg cfg
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
-> SafeReqM cfg (Config cfg)
forall cfg a.
ExceptT HttpException (ReaderT (Config cfg) IO) a -> SafeReqM cfg a
SafeReqM (ReaderT (Config cfg) IO (Config cfg)
-> ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT (Config cfg) IO (Config cfg)
forall (m :: Type -> Type) r. Monad m => ReaderT r m r
ask)
instance MonadBase IO (SafeReqM cfg) where
liftBase :: IO α -> SafeReqM cfg α
liftBase = IO α -> SafeReqM cfg α
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO
instance MonadHttp (SafeReqM cfg) where
handleHttpException :: HttpException -> SafeReqM cfg a
handleHttpException = ExceptT HttpException (ReaderT (Config cfg) IO) a -> SafeReqM cfg a
forall cfg a.
ExceptT HttpException (ReaderT (Config cfg) IO) a -> SafeReqM cfg a
SafeReqM (ExceptT HttpException (ReaderT (Config cfg) IO) a
-> SafeReqM cfg a)
-> (HttpException
-> ExceptT HttpException (ReaderT (Config cfg) IO) a)
-> HttpException
-> SafeReqM cfg a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HttpException -> ExceptT HttpException (ReaderT (Config cfg) IO) a
forall e (m :: Type -> Type) a. MonadError e m => e -> m a
throwError
getHttpConfig :: SafeReqM cfg HttpConfig
getHttpConfig = Config cfg -> HttpConfig
forall cfg. Config cfg -> HttpConfig
httpConfig (Config cfg -> HttpConfig)
-> SafeReqM cfg (Config cfg) -> SafeReqM cfg HttpConfig
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
-> SafeReqM cfg (Config cfg)
forall cfg a.
ExceptT HttpException (ReaderT (Config cfg) IO) a -> SafeReqM cfg a
SafeReqM (ReaderT (Config cfg) IO (Config cfg)
-> ExceptT HttpException (ReaderT (Config cfg) IO) (Config cfg)
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ReaderT (Config cfg) IO (Config cfg)
forall (m :: Type -> Type) r. Monad m => ReaderT r m r
ask)
runSafeReqM ::
MonadIO m
=> Config cfg
-> SafeReqM cfg a
-> m (Either HttpException a)
runSafeReqM :: Config cfg -> SafeReqM cfg a -> m (Either HttpException a)
runSafeReqM Config cfg
config (SafeReqM ExceptT HttpException (ReaderT (Config cfg) IO) a
m) = IO (Either HttpException a) -> m (Either HttpException a)
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (ReaderT (Config cfg) IO (Either HttpException a)
-> Config cfg -> IO (Either HttpException a)
forall r (m :: Type -> Type) a. ReaderT r m a -> r -> m a
runReaderT (ExceptT HttpException (ReaderT (Config cfg) IO) a
-> ReaderT (Config cfg) IO (Either HttpException a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT ExceptT HttpException (ReaderT (Config cfg) IO) a
m) Config cfg
config)