-- | Lifted "System.IO".
module Effectful.FileSystem.IO
  ( -- * Effect
    FileSystem

    -- ** Handlers
  , runFileSystem

    -- * 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
  ) where

import System.IO (Handle, IOMode (..))
import qualified System.IO as IO

import Effectful
import Effectful.Dispatch.Static
import Effectful.FileSystem.Effect

-- | Lifted 'IO.withFile'.
withFile
  :: FileSystem :> es
  => FilePath
  -> IOMode
  -> (Handle -> Eff es a)
  -> Eff es a
withFile :: forall (es :: [Effect]) a.
(FileSystem :> es) =>
FilePath -> IOMode -> (Handle -> Eff es a) -> Eff es a
withFile FilePath
fp IOMode
mode Handle -> Eff es a
inner = forall (es :: [Effect]) a.
HasCallStack =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
unsafeSeqUnliftIO forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
  forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
IO.withFile FilePath
fp IOMode
mode forall a b. (a -> b) -> a -> b
$ forall r. Eff es r -> IO r
unlift forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Eff es a
inner

-- | Lifted 'IO.withBinaryFile'.
withBinaryFile
  :: FileSystem :> es
  => FilePath
  -> IOMode
  -> (Handle -> Eff es a)
  -> Eff es a
withBinaryFile :: forall (es :: [Effect]) a.
(FileSystem :> es) =>
FilePath -> IOMode -> (Handle -> Eff es a) -> Eff es a
withBinaryFile FilePath
fp IOMode
mode Handle -> Eff es a
inner = forall (es :: [Effect]) a.
HasCallStack =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
unsafeSeqUnliftIO forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
  forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
IO.withBinaryFile FilePath
fp IOMode
mode forall a b. (a -> b) -> a -> b
$ forall r. Eff es r -> IO r
unlift forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Eff es a
inner

-- | Lifted 'IO.openFile'
openFile :: FileSystem :> es => FilePath -> IOMode -> Eff es Handle
openFile :: forall (es :: [Effect]).
(FileSystem :> es) =>
FilePath -> IOMode -> Eff es Handle
openFile FilePath
fp = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IOMode -> IO Handle
IO.openFile FilePath
fp

-- | Lifted 'IO.hClose'
hClose :: FileSystem :> es => Handle -> Eff es ()
hClose :: forall (es :: [Effect]). (FileSystem :> es) => Handle -> Eff es ()
hClose = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ()
IO.hClose

-- | Lifted 'IO.hFlush'
hFlush :: FileSystem :> es => Handle -> Eff es ()
hFlush :: forall (es :: [Effect]). (FileSystem :> es) => Handle -> Eff es ()
hFlush = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ()
IO.hFlush

-- | Lifted 'IO.hFileSize'
hFileSize :: FileSystem :> es => Handle -> Eff es Integer
hFileSize :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Integer
hFileSize = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Integer
IO.hFileSize

-- | Lifted 'IO.hSetFileSize'
hSetFileSize :: FileSystem :> es => Handle -> Integer -> Eff es ()
hSetFileSize :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Integer -> Eff es ()
hSetFileSize Handle
h = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Integer -> IO ()
IO.hSetFileSize Handle
h

-- | Lifted 'IO.hIsEOF'
hIsEOF :: FileSystem :> es => Handle -> Eff es Bool
hIsEOF :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsEOF = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsEOF

-- | Lifted 'IO.hSetBuffering'
hSetBuffering :: FileSystem :> es => Handle -> IO.BufferMode -> Eff es ()
hSetBuffering :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> BufferMode -> Eff es ()
hSetBuffering Handle
h = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> BufferMode -> IO ()
IO.hSetBuffering Handle
h

-- | Lifted 'IO.hGetBuffering'
hGetBuffering :: FileSystem :> es => Handle -> Eff es IO.BufferMode
hGetBuffering :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es BufferMode
hGetBuffering = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO BufferMode
IO.hGetBuffering

-- | Lifted 'IO.hSeek'
hSeek :: FileSystem :> es => Handle -> IO.SeekMode -> Integer -> Eff es ()
hSeek :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> SeekMode -> Integer -> Eff es ()
hSeek Handle
h SeekMode
s = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> SeekMode -> Integer -> IO ()
IO.hSeek Handle
h SeekMode
s

-- | Lifted 'IO.hTell'
hTell :: FileSystem :> es => Handle -> Eff es Integer
hTell :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Integer
hTell = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Integer
IO.hTell

-- | Lifted 'IO.hIsOpen'
hIsOpen :: FileSystem :> es => Handle -> Eff es Bool
hIsOpen :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsOpen = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsOpen

-- | Lifted 'IO.hIsClosed'
hIsClosed :: FileSystem :> es => Handle -> Eff es Bool
hIsClosed :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsClosed = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsClosed

-- | Lifted 'IO.hIsReadable'
hIsReadable :: FileSystem :> es => Handle -> Eff es Bool
hIsReadable :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsReadable = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsReadable

-- | Lifted 'IO.hIsWritable'
hIsWritable :: FileSystem :> es => Handle -> Eff es Bool
hIsWritable :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsWritable = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsWritable

-- | Lifted 'IO.hIsSeekable'
hIsSeekable :: FileSystem :> es => Handle -> Eff es Bool
hIsSeekable :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsSeekable = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsSeekable

-- | Lifted 'IO.hIsTerminalDevice'
hIsTerminalDevice :: FileSystem :> es => Handle -> Eff es Bool
hIsTerminalDevice :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hIsTerminalDevice = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hIsTerminalDevice

-- | Lifted 'IO.hSetEcho'
hSetEcho :: FileSystem :> es => Handle -> Bool -> Eff es ()
hSetEcho :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Bool -> Eff es ()
hSetEcho Handle
h = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Bool -> IO ()
IO.hSetEcho Handle
h

-- | Lifted 'IO.hGetEcho'
hGetEcho :: FileSystem :> es => Handle -> Eff es Bool
hGetEcho :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hGetEcho = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hGetEcho

-- | Lifted 'IO.hWaitForInput'
hWaitForInput :: FileSystem :> es => Handle -> Int -> Eff es Bool
hWaitForInput :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Int -> Eff es Bool
hWaitForInput Handle
h = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Int -> IO Bool
IO.hWaitForInput Handle
h

-- | Lifted 'IO.hReady'
hReady :: FileSystem :> es => Handle -> Eff es Bool
hReady :: forall (es :: [Effect]).
(FileSystem :> es) =>
Handle -> Eff es Bool
hReady = forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Bool
IO.hReady