    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