{-# LANGUAGE CPP          #-}
{-# LANGUAGE TypeFamilies #-}
module Data.IOData where

import           Control.Monad                 (liftM)
import           Control.Monad.IO.Class
import qualified Data.ByteString               as ByteString
import qualified Data.ByteString.Char8         as ByteString8
import qualified Data.ByteString.Lazy          as LByteString
import           Data.ByteString.Lazy.Internal (defaultChunkSize)
import qualified Data.Text                     as Text
import qualified Data.Text.IO                  as Text
import qualified Data.Text.Lazy                as LText
import qualified Data.Text.Lazy.IO             as LText
import           Prelude                       (Char, flip, ($), (.), FilePath)
import qualified Prelude
import           System.IO                     (Handle)
import qualified System.IO

#if !MIN_VERSION_text(0, 11, 3)
import           Control.Exception             (handle, throwIO)
import           System.IO.Error               (isEOFError)
#endif

-- | Data which can be read to and from files and handles.
--
-- Note that, for lazy sequences, these operations may perform
-- lazy I\/O.
class IOData a where
    readFile     :: MonadIO m => FilePath -> m a
    writeFile    :: MonadIO m => FilePath -> a -> m ()
    getLine      :: MonadIO m => m a
    hGetContents :: MonadIO m => Handle -> m a
    hGetLine     :: MonadIO m => Handle -> m a
    hPut         :: MonadIO m => Handle -> a -> m ()
    hPutStrLn    :: MonadIO m => Handle -> a -> m ()
    hGetChunk    :: MonadIO m => Handle -> m a
instance IOData ByteString.ByteString where
    readFile :: forall (m :: * -> *). MonadIO m => FilePath -> m ByteString
readFile = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ByteString
ByteString.readFile
    writeFile :: forall (m :: * -> *). MonadIO m => FilePath -> ByteString -> m ()
writeFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ByteString -> IO ()
ByteString.writeFile FilePath
fp
    getLine :: forall (m :: * -> *). MonadIO m => m ByteString
getLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
ByteString.getLine
    hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetContents = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ByteString
ByteString.hGetContents
    hGetLine :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ByteString
ByteString.hGetLine
    hPut :: forall (m :: * -> *). MonadIO m => Handle -> ByteString -> m ()
hPut Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> ByteString -> IO ()
ByteString.hPut Handle
h
    hPutStrLn :: forall (m :: * -> *). MonadIO m => Handle -> ByteString -> m ()
hPutStrLn Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> ByteString -> IO ()
ByteString8.hPutStrLn Handle
h
    hGetChunk :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetChunk = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip Handle -> Int -> IO ByteString
ByteString.hGetSome Int
defaultChunkSize
instance IOData LByteString.ByteString where
    readFile :: forall (m :: * -> *). MonadIO m => FilePath -> m ByteString
readFile = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO ByteString
LByteString.readFile
    writeFile :: forall (m :: * -> *). MonadIO m => FilePath -> ByteString -> m ()
writeFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ByteString -> IO ()
LByteString.writeFile FilePath
fp
    getLine :: forall (m :: * -> *). MonadIO m => m ByteString
getLine = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ByteString -> ByteString
LByteString.fromStrict (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
ByteString.getLine)
    hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetContents = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ByteString
LByteString.hGetContents
    hGetLine :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetLine = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ByteString -> ByteString
LByteString.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ByteString
ByteString.hGetLine
    hPut :: forall (m :: * -> *). MonadIO m => Handle -> ByteString -> m ()
hPut Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> ByteString -> IO ()
LByteString.hPut Handle
h
    hPutStrLn :: forall (m :: * -> *). MonadIO m => Handle -> ByteString -> m ()
hPutStrLn Handle
h ByteString
lbs = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
        Handle -> ByteString -> IO ()
LByteString.hPutStr Handle
h ByteString
lbs
        Handle -> ByteString -> IO ()
ByteString8.hPutStrLn Handle
h ByteString
ByteString.empty
    hGetChunk :: forall (m :: * -> *). MonadIO m => Handle -> m ByteString
hGetChunk = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ByteString -> ByteString
LByteString.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (IOData a, MonadIO m) => Handle -> m a
hGetChunk
instance IOData Text.Text where
    readFile :: forall (m :: * -> *). MonadIO m => FilePath -> m Text
readFile = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO Text
Text.readFile
    writeFile :: forall (m :: * -> *). MonadIO m => FilePath -> Text -> m ()
writeFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text -> IO ()
Text.writeFile FilePath
fp
    getLine :: forall (m :: * -> *). MonadIO m => m Text
getLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Text
Text.getLine
    hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetContents = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Text
Text.hGetContents
    hGetLine :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Text
Text.hGetLine
    hPut :: forall (m :: * -> *). MonadIO m => Handle -> Text -> m ()
hPut Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Text -> IO ()
Text.hPutStr Handle
h
    hPutStrLn :: forall (m :: * -> *). MonadIO m => Handle -> Text -> m ()
hPutStrLn Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Text -> IO ()
Text.hPutStrLn Handle
h
#if MIN_VERSION_text(0, 11, 3)
    hGetChunk :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetChunk = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Text
Text.hGetChunk
#else
    -- Dangerously inefficient!
    hGetChunk =
        liftIO . handleEOF . liftM Text.singleton . System.IO.hGetChar
      where
        handleEOF = handle $ \e ->
            if isEOFError e
                then Prelude.return Text.empty
                else throwIO e
#endif
instance IOData LText.Text where
    readFile :: forall (m :: * -> *). MonadIO m => FilePath -> m Text
readFile = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO Text
LText.readFile
    writeFile :: forall (m :: * -> *). MonadIO m => FilePath -> Text -> m ()
writeFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text -> IO ()
LText.writeFile FilePath
fp
    getLine :: forall (m :: * -> *). MonadIO m => m Text
getLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Text
LText.getLine
    hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetContents = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Text
LText.hGetContents
    hGetLine :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO Text
LText.hGetLine
    hPut :: forall (m :: * -> *). MonadIO m => Handle -> Text -> m ()
hPut Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Text -> IO ()
LText.hPutStr Handle
h
    hPutStrLn :: forall (m :: * -> *). MonadIO m => Handle -> Text -> m ()
hPutStrLn Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Text -> IO ()
LText.hPutStrLn Handle
h
    hGetChunk :: forall (m :: * -> *). MonadIO m => Handle -> m Text
hGetChunk = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Text -> Text
LText.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (IOData a, MonadIO m) => Handle -> m a
hGetChunk
instance (Char ~ c) => IOData [c] where
    readFile :: forall (m :: * -> *). MonadIO m => FilePath -> m [c]
readFile = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO FilePath
Prelude.readFile
    writeFile :: forall (m :: * -> *). MonadIO m => FilePath -> [c] -> m ()
writeFile FilePath
fp = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath -> IO ()
Prelude.writeFile FilePath
fp
    getLine :: forall (m :: * -> *). MonadIO m => m [c]
getLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO FilePath
Prelude.getLine
    hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> m [c]
hGetContents = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO FilePath
System.IO.hGetContents
    hGetLine :: forall (m :: * -> *). MonadIO m => Handle -> m [c]
hGetLine = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO FilePath
System.IO.hGetLine
    hPut :: forall (m :: * -> *). MonadIO m => Handle -> [c] -> m ()
hPut Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> FilePath -> IO ()
System.IO.hPutStr Handle
h
    hPutStrLn :: forall (m :: * -> *). MonadIO m => Handle -> [c] -> m ()
hPutStrLn Handle
h = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> FilePath -> IO ()
System.IO.hPutStrLn Handle
h
    hGetChunk :: forall (m :: * -> *). MonadIO m => Handle -> m [c]
hGetChunk = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Text -> FilePath
Text.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *). (IOData a, MonadIO m) => Handle -> m a
hGetChunk