{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
module Web.Spock.Internal.Monad where

import Web.Spock.Internal.Types

import Control.Monad.Reader
import Control.Monad.Trans.Resource
import Data.Pool

webM :: 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
webM = WebStateM conn sess st a -> t (WebStateM conn sess st) 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 :: (SpockConn (t (WebStateM conn sess st)) -> IO a)
-> t (WebStateM conn sess st) a
runQuery a :: 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 :: (SpockConn (WebStateM conn sess st) -> IO a)
-> WebStateM conn sess st a
runQuery = (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 (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
     (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
     (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 :: WebStateM conn sess st (SpockCfg conn sess st)
getSpockCfgImpl = (WebState conn sess st -> SpockCfg conn sess st)
-> WebStateM conn sess st (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 :: (conn -> IO a) -> WebStateM conn sess st a
runQueryImpl query :: conn -> IO a
query =
    do Pool conn
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
       IO a -> WebStateM conn sess st a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Pool conn -> (conn -> IO a) -> IO a
forall (m :: * -> *) a b.
MonadBaseControl IO m =>
Pool a -> (a -> m b) -> m b
withResource Pool conn
pool conn -> IO a
query)

getStateImpl :: WebStateM conn sess st st
getStateImpl :: WebStateM conn sess st st
getStateImpl = (WebState conn sess st -> st) -> WebStateM conn sess st 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 :: t (WebStateM conn sess st) (WebState conn sess st)
getSpockHeart = WebStateM conn sess st (WebState conn sess st)
-> t (WebStateM conn sess st) (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 :: WebState conn sess st -> WebStateM conn sess st a -> IO a
runSpockIO st :: WebState conn sess st
st (WebStateT action :: 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 :: WebStateM conn sess st (SpockSessionManager conn sess st)
getSessMgrImpl = (WebState conn sess st -> SpockSessionManager conn sess st)
-> WebStateM conn sess st (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 :: t (WebStateM conn sess st) (Pool conn)
getSpockPool = WebStateM conn sess st (Pool conn)
-> t (WebStateM conn sess st) (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 (WebStateM conn sess st) (Pool conn))
-> WebStateM conn sess st (Pool conn)
-> t (WebStateM conn sess st) (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