{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Web.Spock.Internal.Monad where

import Control.Monad.Reader
import Control.Monad.Trans.Resource
import Data.Pool
import Web.Spock.Internal.Types

webM :: MonadTrans t => WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM :: forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM = WebStateT conn sess st (ResourceT IO) a
-> t (WebStateT conn sess st (ResourceT IO)) a
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance (MonadTrans t) => HasSpock (t (WebStateM conn sess st)) where
  type SpockConn (t (WebStateM conn sess st)) = conn
  type SpockState (t (WebStateM conn sess st)) = st
  type SpockSession (t (WebStateM conn sess st)) = sess
  runQuery :: forall a.
(SpockConn (t (WebStateM conn sess st)) -> IO a)
-> t (WebStateM conn sess st) a
runQuery SpockConn (t (WebStateM conn sess st)) -> IO a
a = WebStateM conn sess st a -> t (WebStateM conn sess st) a
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM (WebStateM conn sess st a -> t (WebStateM conn sess st) a)
-> WebStateM conn sess st a -> t (WebStateM conn sess st) a
forall a b. (a -> b) -> a -> b
$ (conn -> IO a) -> WebStateM conn sess st a
forall conn a sess st. (conn -> IO a) -> WebStateM conn sess st a
runQueryImpl conn -> IO a
SpockConn (t (WebStateM conn sess st)) -> IO a
a
  getState :: t (WebStateM conn sess st)
  (SpockState (t (WebStateM conn sess st)))
getState = WebStateM conn sess st st -> t (WebStateM conn sess st) st
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM WebStateM conn sess st st
forall conn sess st. WebStateM conn sess st st
getStateImpl
  getSessMgr :: t (WebStateM conn sess st)
  (SpockSessionManager
     (SpockConn (t (WebStateM conn sess st)))
     (SpockSession (t (WebStateM conn sess st)))
     (SpockState (t (WebStateM conn sess st))))
getSessMgr = WebStateM conn sess st (SpockSessionManager conn sess st)
-> t (WebStateM conn sess st) (SpockSessionManager conn sess st)
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM WebStateM conn sess st (SpockSessionManager conn sess st)
forall conn sess st.
WebStateM conn sess st (SpockSessionManager conn sess st)
getSessMgrImpl
  getSpockCfg :: t (WebStateM conn sess st)
  (SpockCfg
     (SpockConn (t (WebStateM conn sess st)))
     (SpockSession (t (WebStateM conn sess st)))
     (SpockState (t (WebStateM conn sess st))))
getSpockCfg = WebStateM conn sess st (SpockCfg conn sess st)
-> t (WebStateM conn sess st) (SpockCfg conn sess st)
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM WebStateM conn sess st (SpockCfg conn sess st)
forall conn sess st. WebStateM conn sess st (SpockCfg conn sess st)
getSpockCfgImpl

instance HasSpock (WebStateM conn sess st) where
  type SpockConn (WebStateM conn sess st) = conn
  type SpockState (WebStateM conn sess st) = st
  type SpockSession (WebStateM conn sess st) = sess
  runQuery :: forall a.
(SpockConn (WebStateM conn sess st) -> IO a)
-> WebStateM conn sess st a
runQuery = (conn -> IO a) -> WebStateM conn sess st a
(SpockConn (WebStateM conn sess st) -> IO a)
-> WebStateM conn sess st a
forall conn a sess st. (conn -> IO a) -> WebStateM conn sess st a
runQueryImpl
  getState :: WebStateM conn sess st (SpockState (WebStateM conn sess st))
getState = WebStateM conn sess st st
WebStateM conn sess st (SpockState (WebStateM conn sess st))
forall conn sess st. WebStateM conn sess st st
getStateImpl
  getSessMgr :: WebStateM
  conn
  sess
  st
  (SpockSessionManager
     (SpockConn (WebStateM conn sess st))
     (SpockSession (WebStateM conn sess st))
     (SpockState (WebStateM conn sess st)))
getSessMgr = WebStateM conn sess st (SpockSessionManager conn sess st)
WebStateM
  conn
  sess
  st
  (SpockSessionManager
     (SpockConn (WebStateM conn sess st))
     (SpockSession (WebStateM conn sess st))
     (SpockState (WebStateM conn sess st)))
forall conn sess st.
WebStateM conn sess st (SpockSessionManager conn sess st)
getSessMgrImpl
  getSpockCfg :: WebStateM
  conn
  sess
  st
  (SpockCfg
     (SpockConn (WebStateM conn sess st))
     (SpockSession (WebStateM conn sess st))
     (SpockState (WebStateM conn sess st)))
getSpockCfg = WebStateM conn sess st (SpockCfg conn sess st)
WebStateM
  conn
  sess
  st
  (SpockCfg
     (SpockConn (WebStateM conn sess st))
     (SpockSession (WebStateM conn sess st))
     (SpockState (WebStateM conn sess st)))
forall conn sess st. WebStateM conn sess st (SpockCfg conn sess st)
getSpockCfgImpl

getSpockCfgImpl :: WebStateM conn sess st (SpockCfg conn sess st)
getSpockCfgImpl :: forall conn sess st. WebStateM conn sess st (SpockCfg conn sess st)
getSpockCfgImpl = (WebState conn sess st -> SpockCfg conn sess st)
-> WebStateT conn sess st (ResourceT IO) (SpockCfg conn sess st)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WebState conn sess st -> SpockCfg conn sess st
forall conn sess st. WebState conn sess st -> SpockCfg conn sess st
web_config

runQueryImpl :: (conn -> IO a) -> WebStateM conn sess st a
runQueryImpl :: forall conn a sess st. (conn -> IO a) -> WebStateM conn sess st a
runQueryImpl conn -> IO a
query =
  do
    pool <- (WebState conn sess st -> Pool conn)
-> WebStateT conn sess st (ResourceT IO) (Pool conn)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WebState conn sess st -> Pool conn
forall conn sess st. WebState conn sess st -> Pool conn
web_dbConn
    liftIO (withResource pool query)

getStateImpl :: WebStateM conn sess st st
getStateImpl :: forall conn sess st. WebStateM conn sess st st
getStateImpl = (WebState conn sess st -> st)
-> WebStateT conn sess st (ResourceT IO) st
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WebState conn sess st -> st
forall conn sess st. WebState conn sess st -> st
web_state

-- | Read the heart of Spock. This is useful if you want to construct your own
-- monads that work with 'runQuery' and 'getState' using 'runSpockIO'
getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st)
getSpockHeart :: forall (t :: (* -> *) -> * -> *) conn sess st.
MonadTrans t =>
t (WebStateM conn sess st) (WebState conn sess st)
getSpockHeart = WebStateM conn sess st (WebState conn sess st)
-> t (WebStateT conn sess st (ResourceT IO))
     (WebState conn sess st)
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM WebStateM conn sess st (WebState conn sess st)
forall r (m :: * -> *). MonadReader r m => m r
ask

-- | Run an action inside of Spocks core monad. This allows
-- you to use 'runQuery' and 'getState'
runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a
runSpockIO :: forall conn sess st a.
WebState conn sess st -> WebStateM conn sess st a -> IO a
runSpockIO WebState conn sess st
st (WebStateT ReaderT (WebState conn sess st) (ResourceT IO) a
action) =
  ResourceT IO a -> IO a
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (ResourceT IO a -> IO a) -> ResourceT IO a -> IO a
forall a b. (a -> b) -> a -> b
$
    ReaderT (WebState conn sess st) (ResourceT IO) a
-> WebState conn sess st -> ResourceT IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (WebState conn sess st) (ResourceT IO) a
action WebState conn sess st
st

getSessMgrImpl :: WebStateM conn sess st (SpockSessionManager conn sess st)
getSessMgrImpl :: forall conn sess st.
WebStateM conn sess st (SpockSessionManager conn sess st)
getSessMgrImpl = (WebState conn sess st -> SpockSessionManager conn sess st)
-> WebStateT
     conn sess st (ResourceT IO) (SpockSessionManager conn sess st)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WebState conn sess st -> SpockSessionManager conn sess st
forall conn sess st.
WebState conn sess st -> SpockSessionManager conn sess st
web_sessionMgr

-- | Read the connection pool of Spock. This is useful if you want to construct your own
-- monads that work with 'runQuery' and 'getState' using 'runSpockIO'
getSpockPool :: MonadTrans t => t (WebStateM conn sess st) (Pool conn)
getSpockPool :: forall (t :: (* -> *) -> * -> *) conn sess st.
MonadTrans t =>
t (WebStateM conn sess st) (Pool conn)
getSpockPool = WebStateM conn sess st (Pool conn)
-> t (WebStateT conn sess st (ResourceT IO)) (Pool conn)
forall (t :: (* -> *) -> * -> *) conn sess st a.
MonadTrans t =>
WebStateM conn sess st a -> t (WebStateM conn sess st) a
webM (WebStateM conn sess st (Pool conn)
 -> t (WebStateT conn sess st (ResourceT IO)) (Pool conn))
-> WebStateM conn sess st (Pool conn)
-> t (WebStateT conn sess st (ResourceT IO)) (Pool conn)
forall a b. (a -> b) -> a -> b
$ (WebState conn sess st -> Pool conn)
-> WebStateM conn sess st (Pool conn)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks WebState conn sess st -> Pool conn
forall conn sess st. WebState conn sess st -> Pool conn
web_dbConn