module Resource.Region
  ( run
  , exec
  , eval

  , local
  , local_

  , register_
  , attach
  , attachAsync

  , logDebug

  , ReleaseKey
  , ResourceT.release
  ) where

import RIO hiding (local, logDebug)

import Control.Monad.Trans.Resource (MonadResource, ResourceT, ReleaseKey)
import Control.Monad.Trans.Resource qualified as ResourceT
import GHC.Stack (withFrozenCallStack)
import RIO qualified

run :: MonadResource m => ResourceT m a -> m (ReleaseKey, a)
run :: forall (m :: * -> *) a.
MonadResource m =>
ResourceT m a -> m (ReleaseKey, a)
run ResourceT m a
action = do
  InternalState
regionResource <- forall (m :: * -> *). MonadIO m => m InternalState
ResourceT.createInternalState
  ReleaseKey
regionKey <- forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
ResourceT.register forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). MonadIO m => InternalState -> m ()
ResourceT.closeInternalState InternalState
regionResource
  a
resource <- forall (m :: * -> *) a. ResourceT m a -> InternalState -> m a
ResourceT.runInternalState ResourceT m a
action InternalState
regionResource
  pure (ReleaseKey
regionKey, a
resource)

exec :: MonadResource m => ResourceT m a -> m ReleaseKey
exec :: forall (m :: * -> *) a.
MonadResource m =>
ResourceT m a -> m ReleaseKey
exec = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MonadResource m =>
ResourceT m a -> m (ReleaseKey, a)
run

eval :: MonadResource m => ResourceT m a -> m a
eval :: forall (m :: * -> *) a. MonadResource m => ResourceT m a -> m a
eval = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MonadResource m =>
ResourceT m a -> m (ReleaseKey, a)
run

local :: MonadResource m => m (ReleaseKey, a) -> ResourceT m a
local :: forall (m :: * -> *) a.
MonadResource m =>
m (ReleaseKey, a) -> ResourceT m a
local m (ReleaseKey, a)
action = do
  (ReleaseKey
key, a
resource) <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (ReleaseKey, a)
action
  forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
ResourceT.register forall a b. (a -> b) -> a -> b
$
    forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
ResourceT.release ReleaseKey
key
  pure a
resource

local_ :: MonadResource m => m ReleaseKey -> ResourceT m ()
local_ :: forall (m :: * -> *).
MonadResource m =>
m ReleaseKey -> ResourceT m ()
local_ m ReleaseKey
action = do
  ReleaseKey
key <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ReleaseKey
action
  forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
ResourceT.register forall a b. (a -> b) -> a -> b
$
    forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
ResourceT.release ReleaseKey
key

register_ :: MonadUnliftIO m => IO () -> ResourceT m ()
register_ :: forall (m :: * -> *). MonadUnliftIO m => IO () -> ResourceT m ()
register_ = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
ResourceT.register

attach :: MonadUnliftIO m => ReleaseKey -> ResourceT m ()
attach :: forall (m :: * -> *).
MonadUnliftIO m =>
ReleaseKey -> ResourceT m ()
attach = forall (m :: * -> *). MonadUnliftIO m => IO () -> ResourceT m ()
register_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
ResourceT.release

attachAsync :: MonadUnliftIO m => Async a -> ResourceT m ()
attachAsync :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Async a -> ResourceT m ()
attachAsync = forall (m :: * -> *). MonadUnliftIO m => IO () -> ResourceT m ()
register_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => Async a -> m ()
cancel

logDebug
  :: ( MonadUnliftIO m
     , MonadReader env m, HasLogFunc env
     , HasCallStack
     )
  => Utf8Builder
  -> Utf8Builder
  -> ResourceT m ()
logDebug :: forall (m :: * -> *) env.
(MonadUnliftIO m, MonadReader env m, HasLogFunc env,
 HasCallStack) =>
Utf8Builder -> Utf8Builder -> ResourceT m ()
logDebug Utf8Builder
enter Utf8Builder
leave = forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ do
  forall (m :: * -> *) env.
(MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) =>
Utf8Builder -> m ()
RIO.logDebug Utf8Builder
enter
  forall (m :: * -> *) a. MonadUnliftIO m => m a -> m (IO a)
toIO (forall (m :: * -> *) env.
(MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) =>
Utf8Builder -> m ()
RIO.logDebug Utf8Builder
leave) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *). MonadUnliftIO m => IO () -> ResourceT m ()
register_