{-# LANGUAGE TemplateHaskell #-} {-| Module: IO Description: General IO functions specialized for 'Printable' instances. Copyright: © 2016 All rights reserved. License: GPL-3 Maintainer: Evan Cofsky Stability: experimental Portability: POSIX -} module IO ( putStr, putStrLn, managed, Managed, MonadManaged(..), runManaged, TempFile, tfPath, tfHandle, tempFile, MonadIO, liftIO, PIO.hSeek, PIO.SeekMode(..), PIO.IOMode(..), file, tfile, textMode, binaryMode, hIsEOF, hClose, doesFileExist, removeFile, PIO.Handle ) where import Lawless import Control.Monad.IO.Class import qualified System.Path.Directory as D import qualified System.Path.IO as PIO import qualified Data.Text.IO as T import Text import Textual import Path import qualified System.Path.PartClass as PC import Control.Monad.Managed.Safe import Exception import qualified System.IO as SIO -- * Printable I/O to stdio liftPrintble ∷ (MonadIO m, Printable p) ⇒ (Text → IO ()) → p → m () liftPrintble f p = liftIO $ f (buildText ∘ print $ p) putStr ∷ (MonadIO m, Printable p) ⇒ p → m () putStr = liftPrintble T.putStr putStrLn ∷ (MonadIO m, Printable p) ⇒ p → m () putStrLn = liftPrintble T.putStrLn -- * Managed temporary files data TempFile = TempFile { _tfPath ∷ AbsFile, _tfHandle ∷ PIO.Handle } makeLenses ''TempFile tempFile ∷ AbsDir → RelFile → Managed TempFile tempFile pth tmpl = let open = do (p, h) ← liftIO $ PIO.openTempFile pth tmpl liftIO $ binaryMode h return $ TempFile p h close tf = do liftIO $ PIO.hClose $ tf ^. tfHandle liftIO $ D.removeFile $ tf ^. tfPath in managed $ bracket open close -- * Managed files -- | Binary files, no buffering. file ∷ PC.AbsRel ar ⇒ File ar → PIO.IOMode → Managed PIO.Handle file pth m = managed $ \fh → do liftIO $ PIO.withBinaryFile pth m $ \h → do binaryMode h fh h -- | Text files, line-buffered. tfile ∷ PC.AbsRel ar ⇒ File ar → PIO.IOMode → Managed PIO.Handle tfile pth m =managed $ \fh → do liftIO $ PIO.withBinaryFile pth m $ \h → do textMode h fh h textMode ∷ MonadIO m ⇒ PIO.Handle → m () textMode h = liftIO $ PIO.hSetBuffering h PIO.LineBuffering >> PIO.hSetBinaryMode h False binaryMode ∷ MonadIO m ⇒ PIO.Handle → m () binaryMode h = liftIO $ PIO.hSetBuffering h PIO.NoBuffering >> PIO.hSetBinaryMode h True -- * Lifted IO hIsEOF ∷ MonadIO m ⇒ SIO.Handle → m Bool hIsEOF = liftIO ∘ SIO.hIsEOF hClose ∷ MonadIO m ⇒ SIO.Handle → m () hClose = liftIO ∘ SIO.hClose doesFileExist ∷ (MonadIO m, PC.AbsRel ar) ⇒ File ar → m Bool doesFileExist = liftIO ∘ D.doesFileExist removeFile ∷ (MonadIO m, PC.AbsRel ar) ⇒ File ar → m () removeFile = liftIO ∘ D.removeFile