    -- |
    -- Module      :  System.AtomicWrite.Writer.String
    -- Copyright   :  © 2015-2019 Stack Builders Inc.
    -- License     :  MIT
    --
    -- Maintainer  :  Stack Builders <hackage@stackbuilders.com>
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Provides functionality to dump the contents of a String
    -- to a file.

    module System.AtomicWrite.Writer.String (atomicWriteFile, atomicWithFile, atomicWriteFileWithMode, atomicWithFileAndMode) where

    import           System.AtomicWrite.Internal (closeAndRename, maybeSetFileMode,
                                                  tempFileFor)

    import           System.IO                   (Handle, hPutStr)

    import           System.Posix.Types          (FileMode)

    -- | Creates or modifies a file atomically on POSIX-compliant
    -- systems while preserving permissions.
    atomicWriteFile ::
      FilePath   -- ^ The path where the file will be updated or created
      -> String  -- ^ The content to write to the file
      -> IO ()
    atomicWriteFile :: FilePath -> FilePath -> IO ()
    atomicWriteFile = (((Handle -> IO ()) -> IO ())
    -> (FilePath -> Handle -> IO ()) -> FilePath -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Handle -> FilePath -> IO ()) -> FilePath -> Handle -> IO ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Handle -> FilePath -> IO ()
    hPutStr) (((Handle -> IO ()) -> IO ()) -> FilePath -> IO ())
    -> (FilePath -> (Handle -> IO ()) -> IO ())
    -> FilePath
    -> FilePath
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFile

    -- | Creates or modifies a file atomically on
    -- POSIX-compliant systems and updates permissions
    atomicWriteFileWithMode ::
      FileMode    -- ^ The mode to set the file to
      -> FilePath -- ^ The path where the file will be updated or created
      -> String   -- ^ The content to write to the file
      -> IO ()
    atomicWriteFileWithMode :: FileMode -> FilePath -> FilePath -> IO ()
    atomicWriteFileWithMode FileMode
    mode = ( ((Handle -> IO ()) -> IO ())
    -> (FilePath -> Handle -> IO ()) -> FilePath -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Handle -> FilePath -> IO ()) -> FilePath -> Handle -> IO ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Handle -> FilePath -> IO ()
    hPutStr)
                                 (((Handle -> IO ()) -> IO ()) -> FilePath -> IO ())
    -> (FilePath -> (Handle -> IO ()) -> IO ())
    -> FilePath
    -> FilePath
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .  FileMode -> FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFileAndMode FileMode
    mode

    -- | A general version of 'atomicWriteFile'
    atomicWithFile :: FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFile :: FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFile = Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFileAndMaybeMode Maybe FileMode
    forall a. Maybe a
    Nothing

    -- | A general version of 'atomicWriteFileWithMode'
    atomicWithFileAndMode :: FileMode
                          -> FilePath
                          -> (Handle -> IO ())
                          -> IO ()
    atomicWithFileAndMode :: FileMode -> FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFileAndMode = Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFileAndMaybeMode (Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO ())
    -> (FileMode -> Maybe FileMode)
    -> FileMode
    -> FilePath
    -> (Handle -> IO ())
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FileMode -> Maybe FileMode
    forall a. a -> Maybe a
    Just

    -- | Helper function
    atomicWithFileAndMaybeMode :: Maybe FileMode
                               -> FilePath
                               -> (Handle -> IO ())
                               -> IO ()
    atomicWithFileAndMaybeMode :: Maybe FileMode -> FilePath -> (Handle -> IO ()) -> IO ()
    atomicWithFileAndMaybeMode Maybe FileMode
    mmode FilePath
    path Handle -> IO ()
    action =
      FilePath -> IO (FilePath, Handle)
    tempFileFor FilePath
    path IO (FilePath, Handle) -> ((FilePath, Handle) -> IO ()) -> IO ()
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \(FilePath
    tmpPath, Handle
    h) -> Handle -> IO ()
    action Handle
    h
                        IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Handle -> FilePath -> FilePath -> IO ()
    closeAndRename Handle
    h FilePath
    tmpPath FilePath
    path
                        IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> FilePath -> Maybe FileMode -> IO ()
    maybeSetFileMode FilePath
    path Maybe FileMode
    mmode