{-# LANGUAGE UndecidableInstances #-}

module Mensam.Server.Application.Configured where

import Mensam.Server.Application.Configured.Acquisition
import Mensam.Server.Application.Configured.Class
import Mensam.Server.Application.Environment.Class
import Mensam.Server.Configuration

import Control.DeepSeq
import Control.Monad.Logger.CallStack
import Control.Monad.Trans
import Control.Monad.Trans.Compose
import Control.Monad.Trans.Control
import Control.Monad.Trans.Control.Identity
import Control.Monad.Trans.Reader
import Data.Kind

type ConfiguredT :: (Type -> Type) -> Type -> Type
newtype ConfiguredT m a = ConfiguredT {forall (m :: * -> *) a.
ConfiguredT m a -> ReaderT Configuration m a
unConfiguredT :: ReaderT Configuration m a}
  deriving newtype (Functor (ConfiguredT m)
Functor (ConfiguredT m) =>
(forall a. a -> ConfiguredT m a)
-> (forall a b.
    ConfiguredT m (a -> b) -> ConfiguredT m a -> ConfiguredT m b)
-> (forall a b c.
    (a -> b -> c)
    -> ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m c)
-> (forall a b.
    ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b)
-> (forall a b.
    ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m a)
-> Applicative (ConfiguredT m)
forall a. a -> ConfiguredT m a
forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m a
forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
forall a b.
ConfiguredT m (a -> b) -> ConfiguredT m a -> ConfiguredT m b
forall a b c.
(a -> b -> c)
-> ConfiguredT m a -> ConfiguredT m b -> ConfiguredT 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 (ConfiguredT m)
forall (m :: * -> *) a. Applicative m => a -> ConfiguredT m a
forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m a
forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m (a -> b) -> ConfiguredT m a -> ConfiguredT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m c
$cpure :: forall (m :: * -> *) a. Applicative m => a -> ConfiguredT m a
pure :: forall a. a -> ConfiguredT m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m (a -> b) -> ConfiguredT m a -> ConfiguredT m b
<*> :: forall a b.
ConfiguredT m (a -> b) -> ConfiguredT m a -> ConfiguredT m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m c
liftA2 :: forall a b c.
(a -> b -> c)
-> ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
*> :: forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m a
<* :: forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m a
Applicative, (forall a b. (a -> b) -> ConfiguredT m a -> ConfiguredT m b)
-> (forall a b. a -> ConfiguredT m b -> ConfiguredT m a)
-> Functor (ConfiguredT m)
forall a b. a -> ConfiguredT m b -> ConfiguredT m a
forall a b. (a -> b) -> ConfiguredT m a -> ConfiguredT m b
forall (m :: * -> *) a b.
Functor m =>
a -> ConfiguredT m b -> ConfiguredT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ConfiguredT m a -> ConfiguredT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> ConfiguredT m a -> ConfiguredT m b
fmap :: forall a b. (a -> b) -> ConfiguredT m a -> ConfiguredT m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> ConfiguredT m b -> ConfiguredT m a
<$ :: forall a b. a -> ConfiguredT m b -> ConfiguredT m a
Functor, Applicative (ConfiguredT m)
Applicative (ConfiguredT m) =>
(forall a b.
 ConfiguredT m a -> (a -> ConfiguredT m b) -> ConfiguredT m b)
-> (forall a b.
    ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b)
-> (forall a. a -> ConfiguredT m a)
-> Monad (ConfiguredT m)
forall a. a -> ConfiguredT m a
forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
forall a b.
ConfiguredT m a -> (a -> ConfiguredT m b) -> ConfiguredT m b
forall (m :: * -> *). Monad m => Applicative (ConfiguredT m)
forall (m :: * -> *) a. Monad m => a -> ConfiguredT m a
forall (m :: * -> *) a b.
Monad m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
forall (m :: * -> *) a b.
Monad m =>
ConfiguredT m a -> (a -> ConfiguredT m b) -> ConfiguredT 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
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
ConfiguredT m a -> (a -> ConfiguredT m b) -> ConfiguredT m b
>>= :: forall a b.
ConfiguredT m a -> (a -> ConfiguredT m b) -> ConfiguredT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
>> :: forall a b. ConfiguredT m a -> ConfiguredT m b -> ConfiguredT m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> ConfiguredT m a
return :: forall a. a -> ConfiguredT m a
Monad)
  deriving newtype ((forall (m :: * -> *). Monad m => Monad (ConfiguredT m)) =>
(forall (m :: * -> *) a. Monad m => m a -> ConfiguredT m a)
-> MonadTrans ConfiguredT
forall (m :: * -> *). Monad m => Monad (ConfiguredT m)
forall (m :: * -> *) a. Monad m => m a -> ConfiguredT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m)) =>
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (m :: * -> *) a. Monad m => m a -> ConfiguredT m a
lift :: forall (m :: * -> *) a. Monad m => m a -> ConfiguredT m a
MonadTrans, MonadTrans ConfiguredT
MonadTrans ConfiguredT =>
(forall (m :: * -> *) a.
 Monad m =>
 (Run ConfiguredT -> m a) -> ConfiguredT m a)
-> (forall (m :: * -> *) a.
    Monad m =>
    m (StT ConfiguredT a) -> ConfiguredT m a)
-> MonadTransControl ConfiguredT
forall (m :: * -> *) a.
Monad m =>
m (StT ConfiguredT a) -> ConfiguredT m a
forall (m :: * -> *) a.
Monad m =>
(Run ConfiguredT -> m a) -> ConfiguredT m a
forall (t :: (* -> *) -> * -> *).
MonadTrans t =>
(forall (m :: * -> *) a. Monad m => (Run t -> m a) -> t m a)
-> (forall (m :: * -> *) a. Monad m => m (StT t a) -> t m a)
-> MonadTransControl t
$cliftWith :: forall (m :: * -> *) a.
Monad m =>
(Run ConfiguredT -> m a) -> ConfiguredT m a
liftWith :: forall (m :: * -> *) a.
Monad m =>
(Run ConfiguredT -> m a) -> ConfiguredT m a
$crestoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT ConfiguredT a) -> ConfiguredT m a
restoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT ConfiguredT a) -> ConfiguredT m a
MonadTransControl, MonadTransControl ConfiguredT
MonadTransControl ConfiguredT =>
(forall (m :: * -> *) a.
 Monad m =>
 ((forall x. ConfiguredT m x -> m x) -> m a) -> ConfiguredT m a)
-> MonadTransControlIdentity ConfiguredT
forall (m :: * -> *) a.
Monad m =>
((forall x. ConfiguredT m x -> m x) -> m a) -> ConfiguredT m a
forall (t :: (* -> *) -> * -> *).
MonadTransControl t =>
(forall (m :: * -> *) a.
 Monad m =>
 ((forall x. t m x -> m x) -> m a) -> t m a)
-> MonadTransControlIdentity t
$cliftWithIdentity :: forall (m :: * -> *) a.
Monad m =>
((forall x. ConfiguredT m x -> m x) -> m a) -> ConfiguredT m a
liftWithIdentity :: forall (m :: * -> *) a.
Monad m =>
((forall x. ConfiguredT m x -> m x) -> m a) -> ConfiguredT m a
MonadTransControlIdentity)

instance Monad m => MonadConfigured (ConfiguredT m) where
  configuration :: ConfiguredT m Configuration
configuration = ReaderT Configuration m Configuration
-> ConfiguredT m Configuration
forall (m :: * -> *) a.
ReaderT Configuration m a -> ConfiguredT m a
ConfiguredT ReaderT Configuration m Configuration
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask

deriving via
  ConfiguredT ((t2 :: (Type -> Type) -> Type -> Type) m)
  instance
    Monad (t2 m) => MonadConfigured (ComposeT ConfiguredT t2 m)

runConfiguredT :: ConfiguredT m a -> Configuration -> m a
runConfiguredT :: forall (m :: * -> *) a. ConfiguredT m a -> Configuration -> m a
runConfiguredT = ReaderT Configuration m a -> Configuration -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (ReaderT Configuration m a -> Configuration -> m a)
-> (ConfiguredT m a -> ReaderT Configuration m a)
-> ConfiguredT m a
-> Configuration
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredT m a -> ReaderT Configuration m a
forall (m :: * -> *) a.
ConfiguredT m a -> ReaderT Configuration m a
unConfiguredT

runAppConfiguredT ::
  (MonadEnvironment m, MonadIO m, MonadLogger m) =>
  ConfiguredT m a ->
  m a
runAppConfiguredT :: forall (m :: * -> *) a.
(MonadEnvironment m, MonadIO m, MonadLogger m) =>
ConfiguredT m a -> m a
runAppConfiguredT ConfiguredT m a
tma = do
  Maybe Configuration
maybeConfig <- m (Maybe Configuration)
forall (m :: * -> *).
(MonadIO m, MonadEnvironment m, MonadLogger m) =>
m (Maybe Configuration)
acquireConfig
  case Maybe Configuration
maybeConfig of
    Maybe Configuration
Nothing -> [Char] -> m a
forall a. HasCallStack => [Char] -> a
error [Char]
"No configuration."
    Just Configuration
config -> ConfiguredT m a -> Configuration -> m a
forall (m :: * -> *) a. ConfiguredT m a -> Configuration -> m a
runConfiguredT ConfiguredT m a
tma (Configuration -> m a) -> Configuration -> m a
forall a b. (a -> b) -> a -> b
$ Configuration -> Configuration
forall a. NFData a => a -> a
force Configuration
config