diff options
| author | adelon <22380201+adelon@users.noreply.github.com> | 2026-08-06 14:28:46 +0200 |
|---|---|---|
| committer | adelon <22380201+adelon@users.noreply.github.com> | 2026-08-06 14:28:46 +0200 |
| commit | e0c34246eddc4470d89af0660fd2a8ddc1b393a5 (patch) | |
| tree | 1cb74e79fc90580e54a0b22918fad8bd6fc174a4 /source/Felix/Output/Atomic.hs | |
| parent | de041252752b9e0358bdba93d8f836ba28aabad8 (diff) | |
Simplify entry/CLI, track slowest ATP tasks
Diffstat (limited to 'source/Felix/Output/Atomic.hs')
| -rw-r--r-- | source/Felix/Output/Atomic.hs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/source/Felix/Output/Atomic.hs b/source/Felix/Output/Atomic.hs new file mode 100644 index 0000000..39ea9c8 --- /dev/null +++ b/source/Felix/Output/Atomic.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +-- | Sibling-temporary replacement for generated byte artifacts. +module Felix.Output.Atomic (writeBytesAtomically) where + +import Base + +import Data.ByteString (ByteString) +import Data.ByteString qualified as ByteString +import System.Directory qualified as Directory +import System.FilePath.Posix qualified as Posix + +writeBytesAtomically :: FilePath -> ByteString -> IO () +writeBytesAtomically destination bytes = do + let directory = Posix.takeDirectory destination + template = Posix.takeFileName destination <> ".tmp" + bracketOnError + (openBinaryTempFileWithDefaultPermissions directory template) + cleanupTemporary + \(temporary, handle) -> do + ByteString.hPut handle bytes + hFlush handle + hClose handle + Directory.renameFile temporary destination + +cleanupTemporary :: (FilePath, Handle) -> IO () +cleanupTemporary (temporary, handle) = do + void (tryIOError (hClose handle)) + void (tryIOError (Directory.removeFile temporary)) |
