module IHP.Controller.Context
( ControllerContext(..)
, newControllerContext
, freeze
, unfreeze
, putContext
, fromContext
, maybeFromContext
, fromFrozenContext
, maybeFromFrozenContext
, ActionType(..)
) where
import Prelude
import Data.IORef (newIORef, readIORef)
import GHC.Records (HasField(..))
import Data.Maybe (fromMaybe)
import qualified Data.TMap as TypeMap
import IHP.FrameworkConfig.Types (FrameworkConfig(..))
import IHP.Log.Types
import System.IO.Unsafe (unsafePerformIO)
import Network.Wai (Request)
import IHP.RequestVault (requestFrameworkConfig)
import IHP.ActionType (ActionType(..))
import IHP.ControllerContext (ControllerContext(..), freeze, unfreeze, putContext, fromContext, maybeFromContext, fromFrozenContext, maybeFromFrozenContext)
newControllerContext :: (?request :: Request) => IO ControllerContext
newControllerContext :: (?request::Request) => IO ControllerContext
newControllerContext = do
customFieldsRef <- TMap -> IO (IORef TMap)
forall a. a -> IO (IORef a)
newIORef (Request -> TMap -> TMap
forall a. Typeable a => a -> TMap -> TMap
TypeMap.insert ?request::Request
Request
?request TMap
TypeMap.empty)
pure ControllerContext { customFieldsRef }
{-# INLINE newControllerContext #-}
instance HasField "request" ControllerContext Request where
getField :: ControllerContext -> Request
getField (FrozenControllerContext { TMap
customFields :: TMap
customFields :: ControllerContext -> TMap
customFields }) =
case forall a. Typeable a => TMap -> Maybe a
TypeMap.lookup @Request TMap
customFields of
Just Request
req -> Request
req
Maybe Request
Nothing -> [Char] -> Request
forall a. HasCallStack => [Char] -> a
error [Char]
"request: Request not found in controller context. Did you forget to call newControllerContext?"
getField (ControllerContext { IORef TMap
customFieldsRef :: ControllerContext -> IORef TMap
customFieldsRef :: IORef TMap
customFieldsRef }) =
IO Request -> Request
forall a. IO a -> a
unsafePerformIO (IO Request -> Request) -> IO Request -> Request
forall a b. (a -> b) -> a -> b
$ do
customFields <- IORef TMap -> IO TMap
forall a. IORef a -> IO a
readIORef IORef TMap
customFieldsRef
case TypeMap.lookup @Request customFields of
Just Request
req -> Request -> IO Request
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Request
req
Maybe Request
Nothing -> [Char] -> IO Request
forall a. HasCallStack => [Char] -> a
error [Char]
"request: Request not found in controller context. Did you forget to call newControllerContext?"
{-# INLINABLE getField #-}
instance HasField "frameworkConfig" ControllerContext FrameworkConfig where
getField :: ControllerContext -> FrameworkConfig
getField ControllerContext
controllerContext = Request -> FrameworkConfig
requestFrameworkConfig ControllerContext
controllerContext.request
{-# INLINABLE getField #-}
instance HasField "logger" ControllerContext Logger where
getField :: ControllerContext -> Logger
getField context :: ControllerContext
context@(FrozenControllerContext { TMap
customFields :: ControllerContext -> TMap
customFields :: TMap
customFields }) = Logger -> Maybe Logger -> Logger
forall a. a -> Maybe a -> a
fromMaybe ControllerContext
context.frameworkConfig.logger (forall a. Typeable a => TMap -> Maybe a
TypeMap.lookup @Logger TMap
customFields)
getField ControllerContext
context = (IO ControllerContext -> ControllerContext
forall a. IO a -> a
unsafePerformIO (ControllerContext -> IO ControllerContext
freeze ControllerContext
context)).logger