-- | This module provides type-safe access to IO operations.
--
--   It is designed to be imported instead of "System.IO".
--   (It is intended to provide versions of functions from that
--   module which have equivalent functionality but are more
--   typesafe). "System.Path" is a companion module providing
--   a type-safe alternative to "System.FilePath".
--
--   You will typically want to import as follows:
--
--   > import Prelude hiding (FilePath)
--   > import qualified System.Path as Path
--   > import qualified System.Path.Directory as Dir
--   > import qualified System.Path.IO as PIO
--
--
-- Ben Moseley - (c) 2009
--
module System.Path.IO
(
  -- * Covers for System.IO functions
  withFile,
  openFile,
  readFile,
  writeFile,
  appendFile,
  withBinaryFile,
  openBinaryFile,
  openTempFile,
  openBinaryTempFile,

  -- * Re-exports
  IO,
  SIO.fixIO,
  Handle,
  SIO.stdin,
  SIO.stdout,
  SIO.stderr,
  SIO.IOMode(..),
  SIO.hClose,
  SIO.hFileSize,
  SIO.hSetFileSize,
  SIO.hIsEOF,
  SIO.isEOF,
  SIO.BufferMode(..),
  SIO.hSetBuffering,
  SIO.hGetBuffering,
  SIO.hFlush,
  SIO.hGetPosn,
  SIO.hSetPosn,
  SIO.HandlePosn,
  SIO.hSeek,
  SIO.SeekMode(..),
  SIO.hTell,
  SIO.hIsOpen,
  SIO.hIsClosed,
  SIO.hIsReadable,
  SIO.hIsWritable,
  SIO.hIsSeekable,
  SIO.hIsTerminalDevice,
  SIO.hSetEcho,
  SIO.hGetEcho,
  SIO.hShow,
  SIO.hWaitForInput,
  SIO.hReady,
  SIO.hGetChar,
  SIO.hGetLine,
  SIO.hLookAhead,
  SIO.hGetContents,
  SIO.hPutChar,
  SIO.hPutStr,
  SIO.hPutStrLn,
  SIO.hPrint,
  interact,
  putChar,
  putStr,
  putStrLn,
  print,
  getChar,
  getLine,
  getContents,
  readIO,
  readLn,
  SIO.hSetBinaryMode,
  SIO.hPutBuf,
  SIO.hGetBuf,
  SIO.hPutBufNonBlocking,
  SIO.hGetBufNonBlocking,
)

where

import qualified System.Path.Internal.PartClass as Class
import qualified System.Path as Path
import System.Path (DirPath, FilePath, AbsFile, RelFile)

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

import Control.Applicative ((<$>))
import Data.Tuple.HT (mapFst)

import Prelude hiding (FilePath, readFile, writeFile, appendFile)


------------------------------------------------------------------------
-- Covers for System.IO functions

withFile ::
    Class.AbsRel ar => FilePath ar -> IOMode -> (Handle -> IO r) -> IO r
withFile :: forall ar r.
AbsRel ar =>
FilePath ar -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath ar
f = FilePath -> IOMode -> (Handle -> IO r) -> IO r
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
SIO.withFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

openFile :: Class.AbsRel ar => FilePath ar -> IOMode -> IO Handle
openFile :: forall ar. AbsRel ar => FilePath ar -> IOMode -> IO Handle
openFile FilePath ar
f = FilePath -> IOMode -> IO Handle
SIO.openFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

readFile :: Class.AbsRel ar => FilePath ar -> IO String
readFile :: forall ar. AbsRel ar => FilePath ar -> IO FilePath
readFile FilePath ar
f = FilePath -> IO FilePath
SIO.readFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

writeFile :: Class.AbsRel ar => FilePath ar -> String -> IO ()
writeFile :: forall ar. AbsRel ar => FilePath ar -> FilePath -> IO ()
writeFile FilePath ar
f = FilePath -> FilePath -> IO ()
SIO.writeFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

appendFile :: Class.AbsRel ar => FilePath ar -> String -> IO ()
appendFile :: forall ar. AbsRel ar => FilePath ar -> FilePath -> IO ()
appendFile FilePath ar
f = FilePath -> FilePath -> IO ()
SIO.appendFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

withBinaryFile ::
    Class.AbsRel ar => FilePath ar -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile :: forall ar r.
AbsRel ar =>
FilePath ar -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile FilePath ar
f = FilePath -> IOMode -> (Handle -> IO r) -> IO r
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
SIO.withBinaryFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

openBinaryFile :: Class.AbsRel ar => FilePath ar -> IOMode -> IO Handle
openBinaryFile :: forall ar. AbsRel ar => FilePath ar -> IOMode -> IO Handle
openBinaryFile FilePath ar
f = FilePath -> IOMode -> IO Handle
SIO.openBinaryFile (FilePath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString FilePath ar
f)

openTempFile ::
    Class.AbsRel ar => DirPath ar -> RelFile -> IO (AbsFile, Handle)
openTempFile :: forall ar.
AbsRel ar =>
DirPath ar -> RelFile -> IO (AbsFile, Handle)
openTempFile DirPath ar
f RelFile
template =
    (FilePath -> AbsFile) -> (FilePath, Handle) -> (AbsFile, Handle)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst FilePath -> AbsFile
Path.absFile ((FilePath, Handle) -> (AbsFile, Handle))
-> IO (FilePath, Handle) -> IO (AbsFile, Handle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FilePath -> FilePath -> IO (FilePath, Handle)
SIO.openTempFile (DirPath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString DirPath ar
f) (RelFile -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString RelFile
template)

openBinaryTempFile ::
    Class.AbsRel ar => DirPath ar -> RelFile -> IO (AbsFile, Handle)
openBinaryTempFile :: forall ar.
AbsRel ar =>
DirPath ar -> RelFile -> IO (AbsFile, Handle)
openBinaryTempFile DirPath ar
f RelFile
template =
    (FilePath -> AbsFile) -> (FilePath, Handle) -> (AbsFile, Handle)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst FilePath -> AbsFile
Path.absFile ((FilePath, Handle) -> (AbsFile, Handle))
-> IO (FilePath, Handle) -> IO (AbsFile, Handle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    FilePath -> FilePath -> IO (FilePath, Handle)
SIO.openBinaryTempFile (DirPath ar -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString DirPath ar
f) (RelFile -> FilePath
forall ar fd. (AbsRel ar, FileDir fd) => Path ar fd -> FilePath
Path.toString RelFile
template)