module System.File.PlatformPath.Internal (
    openBinaryFile
  , withFile
  , withBinaryFile
  , withFile'
  , withBinaryFile'
  , readFile
  , readFile'
  , writeFile
  , writeFile'
  , appendFile
  , appendFile'
  , openFile
  , openExistingFile
  , openFileWithCloseOnExec
  , openExistingFileWithCloseOnExec
  , OsPath.handleFinalizer
  , OsPath.HandleFinalizer
  , OsPath.addHandleFinalizer
  , withOpenFile'
  , addFilePathToIOError
  , augmentError
) where


import System.IO (IOMode(..), Handle)
import System.OsPath.Types
import GHC.IO.Exception (IOException(..))

import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL

import qualified System.File.OsPath.Internal as OsPath
import System.OsString.Internal.Types

import Data.Coerce (coerce)
import Prelude hiding (readFile, writeFile, appendFile)

-- | Like `OsPath.openBinaryFile`, but takes a `PlatformPath` instead of an `OsPath`.
openBinaryFile :: PlatformPath -> IOMode -> IO Handle
openBinaryFile :: PlatformPath -> IOMode -> IO Handle
openBinaryFile = OsPath -> IOMode -> IO Handle
OsPath.openBinaryFile (OsPath -> IOMode -> IO Handle)
-> (PlatformPath -> OsPath) -> PlatformPath -> IOMode -> IO Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.withFile`, but takes a `PlatformPath` instead of an `OsPath`.
withFile :: PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withFile :: forall r. PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withFile = OsPath -> IOMode -> (Handle -> IO r) -> IO r
forall r. OsPath -> IOMode -> (Handle -> IO r) -> IO r
OsPath.withFile (OsPath -> IOMode -> (Handle -> IO r) -> IO r)
-> (PlatformPath -> OsPath)
-> PlatformPath
-> IOMode
-> (Handle -> IO r)
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.withBinaryFile`, but takes a `PlatformPath` instead of an `OsPath`.
withBinaryFile :: PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile :: forall r. PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile = OsPath -> IOMode -> (Handle -> IO r) -> IO r
forall r. OsPath -> IOMode -> (Handle -> IO r) -> IO r
OsPath.withBinaryFile (OsPath -> IOMode -> (Handle -> IO r) -> IO r)
-> (PlatformPath -> OsPath)
-> PlatformPath
-> IOMode
-> (Handle -> IO r)
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.withFile'`, but takes a `PlatformPath` instead of an `OsPath`.
withFile' :: PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withFile' :: forall r. PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withFile' = OsPath -> IOMode -> (Handle -> IO r) -> IO r
forall r. OsPath -> IOMode -> (Handle -> IO r) -> IO r
OsPath.withFile' (OsPath -> IOMode -> (Handle -> IO r) -> IO r)
-> (PlatformPath -> OsPath)
-> PlatformPath
-> IOMode
-> (Handle -> IO r)
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.withBinaryFile'`, but takes a `PlatformPath` instead of an `OsPath`.
withBinaryFile' :: PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile' :: forall r. PlatformPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile' = OsPath -> IOMode -> (Handle -> IO r) -> IO r
forall r. OsPath -> IOMode -> (Handle -> IO r) -> IO r
OsPath.withBinaryFile' (OsPath -> IOMode -> (Handle -> IO r) -> IO r)
-> (PlatformPath -> OsPath)
-> PlatformPath
-> IOMode
-> (Handle -> IO r)
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.readFile`, but takes a `PlatformPath` instead of an `OsPath`.
readFile :: PlatformPath -> IO BSL.ByteString
readFile :: PlatformPath -> IO ByteString
readFile = OsPath -> IO ByteString
OsPath.readFile (OsPath -> IO ByteString)
-> (PlatformPath -> OsPath) -> PlatformPath -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.readFile'`, but takes a `PlatformPath` instead of an `OsPath`.
readFile' :: PlatformPath -> IO BS.ByteString
readFile' :: PlatformPath -> IO ByteString
readFile' = OsPath -> IO ByteString
OsPath.readFile' (OsPath -> IO ByteString)
-> (PlatformPath -> OsPath) -> PlatformPath -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.writeFile`, but takes a `PlatformPath` instead of an `OsPath`.
writeFile :: PlatformPath -> BSL.ByteString -> IO ()
writeFile :: PlatformPath -> ByteString -> IO ()
writeFile = OsPath -> ByteString -> IO ()
OsPath.writeFile (OsPath -> ByteString -> IO ())
-> (PlatformPath -> OsPath) -> PlatformPath -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.writeFile'`, but takes a `PlatformPath` instead of an `OsPath`.
writeFile' :: PlatformPath -> BS.ByteString -> IO ()
writeFile' :: PlatformPath -> ByteString -> IO ()
writeFile' = OsPath -> ByteString -> IO ()
OsPath.writeFile' (OsPath -> ByteString -> IO ())
-> (PlatformPath -> OsPath) -> PlatformPath -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.appendFile`, but takes a `PlatformPath` instead of an `OsPath`.
appendFile :: PlatformPath -> BSL.ByteString -> IO ()
appendFile :: PlatformPath -> ByteString -> IO ()
appendFile = OsPath -> ByteString -> IO ()
OsPath.appendFile (OsPath -> ByteString -> IO ())
-> (PlatformPath -> OsPath) -> PlatformPath -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.appendFile'`, but takes a `PlatformPath` instead of an `OsPath`.
appendFile' :: PlatformPath -> BS.ByteString -> IO ()
appendFile' :: PlatformPath -> ByteString -> IO ()
appendFile' = OsPath -> ByteString -> IO ()
OsPath.appendFile' (OsPath -> ByteString -> IO ())
-> (PlatformPath -> OsPath) -> PlatformPath -> ByteString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.openFile`, but takes a `PlatformPath` instead of an `OsPath`.
openFile :: PlatformPath -> IOMode -> IO Handle
openFile :: PlatformPath -> IOMode -> IO Handle
openFile = OsPath -> IOMode -> IO Handle
OsPath.openFile (OsPath -> IOMode -> IO Handle)
-> (PlatformPath -> OsPath) -> PlatformPath -> IOMode -> IO Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Like `OsPath.openExistingFile`, but takes a `PlatformPath` instead of an `OsPath`.
openExistingFile :: PlatformPath -> IOMode -> IO Handle
openExistingFile :: PlatformPath -> IOMode -> IO Handle
openExistingFile = OsPath -> IOMode -> IO Handle
OsPath.openExistingFile (OsPath -> IOMode -> IO Handle)
-> (PlatformPath -> OsPath) -> PlatformPath -> IOMode -> IO Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Open a file and return the 'Handle'.
--
-- Sets @O_CLOEXEC@ on posix.
--
-- @since 0.1.2
openFileWithCloseOnExec :: PlatformPath -> IOMode -> IO Handle
openFileWithCloseOnExec :: PlatformPath -> IOMode -> IO Handle
openFileWithCloseOnExec = OsPath -> IOMode -> IO Handle
OsPath.openFileWithCloseOnExec (OsPath -> IOMode -> IO Handle)
-> (PlatformPath -> OsPath) -> PlatformPath -> IOMode -> IO Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- | Open an existing file and return the 'Handle'.
--
-- Sets @O_CLOEXEC@ on posix.
--
-- @since 0.1.2
openExistingFileWithCloseOnExec :: PlatformPath -> IOMode -> IO Handle
openExistingFileWithCloseOnExec :: PlatformPath -> IOMode -> IO Handle
openExistingFileWithCloseOnExec = OsPath -> IOMode -> IO Handle
OsPath.openExistingFileWithCloseOnExec (OsPath -> IOMode -> IO Handle)
-> (PlatformPath -> OsPath) -> PlatformPath -> IOMode -> IO Handle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

-- ---------------------------------------------------------------------------
-- Internals

withOpenFile' :: PlatformPath -> IOMode -> Bool -> Bool -> Bool -> (Handle -> IO r) -> Bool -> IO r
withOpenFile' :: forall r.
PlatformPath
-> IOMode
-> Bool
-> Bool
-> Bool
-> (Handle -> IO r)
-> Bool
-> IO r
withOpenFile' = OsPath
-> IOMode
-> Bool
-> Bool
-> Bool
-> (Handle -> IO r)
-> Bool
-> IO r
forall r.
OsPath
-> IOMode
-> Bool
-> Bool
-> Bool
-> (Handle -> IO r)
-> Bool
-> IO r
OsPath.withOpenFile' (OsPath
 -> IOMode
 -> Bool
 -> Bool
 -> Bool
 -> (Handle -> IO r)
 -> Bool
 -> IO r)
-> (PlatformPath -> OsPath)
-> PlatformPath
-> IOMode
-> Bool
-> Bool
-> Bool
-> (Handle -> IO r)
-> Bool
-> IO r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce

addFilePathToIOError :: String -> PlatformPath -> IOException -> IOException
addFilePathToIOError :: String -> PlatformPath -> IOException -> IOException
addFilePathToIOError = (String -> OsPath -> IOException -> IOException)
-> String -> PlatformPath -> IOException -> IOException
forall a b. Coercible a b => a -> b
coerce String -> OsPath -> IOException -> IOException
OsPath.addFilePathToIOError

augmentError :: String -> PlatformPath -> IO a -> IO a
augmentError :: forall a. String -> PlatformPath -> IO a -> IO a
augmentError String
fp = String -> OsPath -> IO a -> IO a
forall a. String -> OsPath -> IO a -> IO a
OsPath.augmentError String
fp (OsPath -> IO a -> IO a)
-> (PlatformPath -> OsPath) -> PlatformPath -> IO a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlatformPath -> OsPath
forall a b. Coercible a b => a -> b
coerce