-- | Unlifted "Control.Monad.Trans.Resource".
--
-- @since 1.1.10
module UnliftIO.Resource
  ( -- * UnliftIO variants
    runResourceT
  , liftResourceT
  , allocateU
    -- * Reexports
  , module Control.Monad.Trans.Resource
  ) where

import qualified Control.Monad.Trans.Resource as Res
import Control.Monad.Trans.Resource.Internal (ResourceT (..))
import Control.Monad.IO.Unlift
import Control.Monad.Trans.Resource (ResourceT, ReleaseKey, allocate, register, release, unprotect, MonadResource)

-- | Unlifted version of 'Res.runResourceT'.
--
-- @since 1.1.10
runResourceT :: MonadUnliftIO m => ResourceT m a -> m a
runResourceT :: forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT ResourceT m a
m = ((forall a. m a -> IO a) -> IO a) -> m a
forall b. ((forall a. m a -> IO a) -> IO b) -> m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO a) -> m a)
-> ((forall a. m a -> IO a) -> IO a) -> m a
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> ResourceT IO a -> IO a
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
Res.runResourceT (ResourceT IO a -> IO a) -> ResourceT IO a -> IO a
forall a b. (a -> b) -> a -> b
$ (m a -> IO a) -> ResourceT m a -> ResourceT IO a
forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
Res.transResourceT m a -> IO a
forall a. m a -> IO a
run ResourceT m a
m

-- | Lifted version of 'Res.liftResourceT'.
--
-- @since 1.1.10
liftResourceT :: MonadIO m => ResourceT IO a -> ResourceT m a
liftResourceT :: forall (m :: * -> *) a.
MonadIO m =>
ResourceT IO a -> ResourceT m a
liftResourceT (ResourceT IORef ReleaseMap -> IO a
f) = (IORef ReleaseMap -> m a) -> ResourceT m a
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT ((IORef ReleaseMap -> m a) -> ResourceT m a)
-> (IORef ReleaseMap -> m a) -> ResourceT m a
forall a b. (a -> b) -> a -> b
$ IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a)
-> (IORef ReleaseMap -> IO a) -> IORef ReleaseMap -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef ReleaseMap -> IO a
f

-- | Unlifted 'allocate'.
--
-- @since 1.2.6
allocateU
  :: (MonadUnliftIO m, MonadResource m)
  => m a
  -> (a -> m ())
  -> m (ReleaseKey, a)
allocateU :: forall (m :: * -> *) a.
(MonadUnliftIO m, MonadResource m) =>
m a -> (a -> m ()) -> m (ReleaseKey, a)
allocateU m a
alloc a -> m ()
free = ((forall a. m a -> IO a) -> IO (ReleaseKey, a))
-> m (ReleaseKey, a)
forall b. ((forall a. m a -> IO a) -> IO b) -> m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO (ReleaseKey, a))
 -> m (ReleaseKey, a))
-> ((forall a. m a -> IO a) -> IO (ReleaseKey, a))
-> m (ReleaseKey, a)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run ->
  m (ReleaseKey, a) -> IO (ReleaseKey, a)
forall a. m a -> IO a
run (m (ReleaseKey, a) -> IO (ReleaseKey, a))
-> m (ReleaseKey, a) -> IO (ReleaseKey, a)
forall a b. (a -> b) -> a -> b
$ IO a -> (a -> IO ()) -> m (ReleaseKey, a)
forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate (m a -> IO a
forall a. m a -> IO a
run m a
alloc) (m () -> IO ()
forall a. m a -> IO a
run (m () -> IO ()) -> (a -> m ()) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m ()
free)