1 
    2 module Store.Temp
    3   ( TempFile(..)
    4   , makeTempFileAs
    5   , makeTempFile
    6   , releaseTempFile
    7   , renameTempFile
    8   ) where
    9 
   10 import Control.Exception (bracket)
   11 import Control.Monad (void)
   12 import Control.Monad.Trans.Resource (InternalState, runInternalState, ReleaseKey, allocate, release, unprotect)
   13 import System.IO (Handle, hClose)
   14 import System.Posix.FilePath (RawFilePath)
   15 import System.Posix.Files.ByteString (removeLink, rename)
   16 import System.Posix.Temp.ByteString (mkstemp)
   17 
   18 import Has (peeks, focusIO, MonadHas)
   19 import Store.Types
   20 -- import Action.Types
   21 
   22 data TempFile = TempFile
   23   { tempFileRelease :: ReleaseKey
   24   , tempFilePath :: RawFilePath
   25   }
   26 
   27 makeTempFileAs :: RawFilePath -> (Handle -> IO ()) -> InternalState -> IO TempFile
   28 makeTempFileAs d g rs = bracket
   29   (runInternalState (allocate (mkstemp d) (removeLink . fst)) rs)
   30   (hClose . snd . snd)
   31   (\(k, (f, h)) -> TempFile k f <$ g h)
   32 
   33 makeTempFile :: (MonadStorage c m, MonadHas InternalState c m) => (Handle -> IO ()) -> m TempFile
   34 makeTempFile f = do
   35   tmp <- peeks storageTemp
   36   focusIO $ makeTempFileAs tmp f
   37 
   38 releaseTempFile :: TempFile -> InternalState -> IO ()
   39 releaseTempFile = runInternalState . release . tempFileRelease
   40 
   41 renameTempFile :: TempFile -> RawFilePath -> InternalState -> IO ()
   42 renameTempFile (TempFile k f) t rs = do
   43   rename f t
   44   void $ runInternalState (unprotect k) rs