{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module ELynx.Tools.InputOutput
(
readGZFile
, writeGZFile
, io
, runParserOnFile
, parseFileWith
, parseIOWith
, parseFileOrIOWith
, parseStringWith
, parseByteStringWith
) where
import Codec.Compression.GZip (compress, decompress)
import Control.Monad.IO.Class
import Control.Monad.Logger
import qualified Data.ByteString.Lazy.Char8 as L
import Data.List (isSuffixOf)
import Data.Maybe
import qualified Data.Text as T
import Text.Megaparsec
readGZFile :: FilePath -> IO L.ByteString
readGZFile f | ".gz" `isSuffixOf` f = decompress <$> L.readFile f
| otherwise = L.readFile f
writeGZFile :: FilePath -> L.ByteString -> IO ()
writeGZFile f | ".gz" `isSuffixOf` f = L.writeFile f . compress
| otherwise = L.writeFile f
runParserOnFile :: Parsec e L.ByteString a
-> FilePath -> IO (Either (ParseErrorBundle L.ByteString e) a)
runParserOnFile p f = parse p f <$> readGZFile f
parseFileWith :: (ShowErrorComponent e)
=> Parsec e L.ByteString a
-> FilePath
-> IO a
parseFileWith p f = parseFileOrIOWith p (Just f)
parseIOWith :: (ShowErrorComponent e)
=> Parsec e L.ByteString a
-> IO a
parseIOWith p = parseByteStringWith "Standard input" p <$> L.getContents
parseFileOrIOWith :: (ShowErrorComponent e)
=> Parsec e L.ByteString a
-> Maybe FilePath
-> IO a
parseFileOrIOWith p mf = do
contents <- case mf of
Nothing -> L.getContents
Just f -> readGZFile f
return $ parseByteStringWith (fromMaybe "Standard input" mf) p contents
parseStringWith :: (ShowErrorComponent e)
=> String
-> Parsec e L.ByteString a
-> String
-> a
parseStringWith s p l = parseByteStringWith s p (L.pack l)
parseByteStringWith :: (ShowErrorComponent e)
=> String
-> Parsec e L.ByteString a
-> L.ByteString
-> a
parseByteStringWith s p l = case parse p s l of
Left err -> error $ errorBundlePretty err
Right val -> val
io :: (MonadLogger m, MonadIO m) => String -> L.ByteString -> Maybe FilePath -> m ()
io name res mfp =
case mfp of
Nothing -> do
$(logInfo) $ T.pack $ "Write " <> name <> " to standard output."
liftIO $ L.putStr res
Just fp -> do
$(logInfo) $ T.pack $ "Write " <> name <> " to file '" <> fp <> "'."
liftIO $ writeGZFile fp res