-- | Unlifted "System.IO".
--
-- @since 0.1.0.0
module UnliftIO.IO
  ( IOMode (..)
  , Handle
  , IO.stdin
  , IO.stdout
  , IO.stderr
  , withFile
  , withBinaryFile
  , openFile
  , hClose
  , hFlush
  , hFileSize
  , hSetFileSize
  , hIsEOF
  , IO.BufferMode (..)
  , hSetBuffering
  , hGetBuffering
  , hSeek
  , IO.SeekMode (..)
  , hTell
  , hIsOpen
  , hIsClosed
  , hIsReadable
  , hIsWritable
  , hIsSeekable
  , hIsTerminalDevice
  , hSetEcho
  , hGetEcho
  , hWaitForInput
  , hReady
  , getMonotonicTime
  ) where

import qualified System.IO as IO
import System.IO (Handle, IOMode (..))
import Control.Monad.IO.Unlift

import System.IO.Unsafe (unsafePerformIO)

-- | Unlifted version of 'IO.withFile'.
--
-- @since 0.1.0.0
withFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
withFile :: forall (m :: * -> *) a.
MonadUnliftIO m =>
FilePath -> IOMode -> (Handle -> m a) -> m a
withFile FilePath
fp IOMode
mode Handle -> m a
inner = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
IO.withFile FilePath
fp IOMode
mode forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> m a
inner

-- | Unlifted version of 'IO.withBinaryFile'.
--
-- @since 0.1.0.0
withBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
withBinaryFile :: forall (m :: * -> *) a.
MonadUnliftIO m =>
FilePath -> IOMode -> (Handle -> m a) -> m a
withBinaryFile FilePath
fp IOMode
mode Handle -> m a
inner = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
IO.withBinaryFile FilePath
fp IOMode
mode forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> m a
inner

-- | Lifted version of 'IO.openFile'
--
-- @since 0.2.20
openFile :: MonadIO m => FilePath -> IOMode -> m Handle
openFile :: forall (m :: * -> *). MonadIO m => FilePath -> IOMode -> m Handle
openFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IOMode -> IO Handle
IO.openFile FilePath
fp

-- | Lifted version of 'IO.hClose'
--
-- @since 0.2.1.0
hClose :: MonadIO m => Handle -> m ()
hClose :: forall (m :: * -> *). MonadIO m => Handle -> m ()
hClose = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ()
IO.hClose

-- | Lifted version of 'IO.hFlush'
--
-- @since 0.2.1.0
hFlush :: MonadIO m => Handle -> m ()
hFlush :: forall (m :: * -> *). MonadIO m => Handle -> m ()
hFlush = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ()
IO.hFlush

-- | Lifted version of 'IO.hFileSize'
--
-- @since 0.2.1.0
hFileSize :: MonadIO m => Handle -> m Integer
hFileSize :: forall (m :: * -> *). MonadIO m => Handle -> m Integer
hFileSize = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Integer
IO.hFileSize

-- | Lifted version of 'IO.hSetFileSize'
--
-- @since 0.2.1.0
hSetFileSize :: MonadIO m => Handle -> Integer -> m ()
hSetFileSize :: forall (m :: * -> *). MonadIO m => Handle -> Integer -> m ()
hSetFileSize Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Integer -> IO ()
IO.hSetFileSize Handle
h

-- | Lifted version of 'IO.hIsEOF'
--
-- @since 0.2.1.0
hIsEOF :: MonadIO m => Handle -> m Bool
hIsEOF :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsEOF = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsEOF

-- | Lifted version of 'IO.hSetBuffering'
--
-- @since 0.2.1.0
hSetBuffering :: MonadIO m => Handle -> IO.BufferMode -> m ()
hSetBuffering :: forall (m :: * -> *). MonadIO m => Handle -> BufferMode -> m ()
hSetBuffering Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> BufferMode -> IO ()
IO.hSetBuffering Handle
h

-- | Lifted version of 'IO.hGetBuffering'
--
-- @since 0.2.1.0
hGetBuffering :: MonadIO m => Handle -> m IO.BufferMode
hGetBuffering :: forall (m :: * -> *). MonadIO m => Handle -> m BufferMode
hGetBuffering = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO BufferMode
IO.hGetBuffering

-- | Lifted version of 'IO.hSeek'
--
-- @since 0.2.1.0
hSeek :: MonadIO m => Handle -> IO.SeekMode -> Integer -> m ()
hSeek :: forall (m :: * -> *).
MonadIO m =>
Handle -> SeekMode -> Integer -> m ()
hSeek Handle
h SeekMode
s = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> SeekMode -> Integer -> IO ()
IO.hSeek Handle
h SeekMode
s

-- | Lifted version of 'IO.hTell'
--
-- @since 0.2.1.0
hTell :: MonadIO m => Handle -> m Integer
hTell :: forall (m :: * -> *). MonadIO m => Handle -> m Integer
hTell = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Integer
IO.hTell

-- | Lifted version of 'IO.hIsOpen'
--
-- @since 0.2.1.0
hIsOpen :: MonadIO m => Handle -> m Bool
hIsOpen :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsOpen = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsOpen

-- | Lifted version of 'IO.hIsClosed'
--
-- @since 0.2.1.0
hIsClosed :: MonadIO m => Handle -> m Bool
hIsClosed :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsClosed = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsClosed

-- | Lifted version of 'IO.hIsReadable'
--
-- @since 0.2.1.0
hIsReadable :: MonadIO m => Handle -> m Bool
hIsReadable :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsReadable = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsReadable

-- | Lifted version of 'IO.hIsWritable'
--
-- @since 0.2.1.0
hIsWritable :: MonadIO m => Handle -> m Bool
hIsWritable :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsWritable = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsWritable

-- | Lifted version of 'IO.hIsSeekable'
--
-- @since 0.2.1.0
hIsSeekable :: MonadIO m => Handle -> m Bool
hIsSeekable :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsSeekable = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsSeekable

-- | Lifted version of 'IO.hIsTerminalDevice'
--
-- @since 0.2.1.0
hIsTerminalDevice :: MonadIO m => Handle -> m Bool
hIsTerminalDevice :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hIsTerminalDevice = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsTerminalDevice

-- | Lifted version of 'IO.hSetEcho'
--
-- @since 0.2.1.0
hSetEcho :: MonadIO m => Handle -> Bool -> m ()
hSetEcho :: forall (m :: * -> *). MonadIO m => Handle -> Bool -> m ()
hSetEcho Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Bool -> IO ()
IO.hSetEcho Handle
h

-- | Lifted version of 'IO.hGetEcho'
--
-- @since 0.2.1.0
hGetEcho :: MonadIO m => Handle -> m Bool
hGetEcho :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hGetEcho = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hGetEcho

-- | Lifted version of 'IO.hWaitForInput'
--
-- @since 0.2.1.0
hWaitForInput :: MonadIO m => Handle -> Int -> m Bool
hWaitForInput :: forall (m :: * -> *). MonadIO m => Handle -> Int -> m Bool
hWaitForInput Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Int -> IO Bool
IO.hWaitForInput Handle
h

-- | Lifted version of 'IO.hReady'
--
-- @since 0.2.1.0
hReady :: MonadIO m => Handle -> m Bool
hReady :: forall (m :: * -> *). MonadIO m => Handle -> m Bool
hReady = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hReady

-- | Get the number of seconds which have passed since an arbitrary starting
-- time, useful for calculating runtime in a program.
--
-- @since 0.2.3.0
getMonotonicTime :: MonadIO m => m Double
getMonotonicTime :: forall (m :: * -> *). MonadIO m => m Double
getMonotonicTime = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ ()
initted seq :: forall a b. a -> b -> b
`seq` IO Double
getMonotonicTime'

-- | Set up time measurement.
foreign import ccall unsafe "unliftio_inittime" initializeTime :: IO ()

initted :: ()
initted :: ()
initted = forall a. IO a -> a
unsafePerformIO IO ()
initializeTime
{-# NOINLINE initted #-}

foreign import ccall unsafe "unliftio_gettime" getMonotonicTime' :: IO Double