X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=Pipes%2FText%2FIO.hs;h=51c69265a04ac49a9aaa047cf7b1952242efdc40;hb=bdc47ebc7bd24c7b123867072c825d42d26ca536;hp=45a146778e58eaa2bfd6e558cb089a508b56234f;hpb=0ac0c414be4f9f20893112ed8ffa4d9cb6646061;p=github%2Ffretlink%2Ftext-pipes.git diff --git a/Pipes/Text/IO.hs b/Pipes/Text/IO.hs index 45a1467..51c6926 100644 --- a/Pipes/Text/IO.hs +++ b/Pipes/Text/IO.hs @@ -11,8 +11,10 @@ module Pipes.Text.IO -- * Producers fromHandle + , fromHandleLn , stdin , readFile + , readFileLn -- * Consumers , toHandle , stdout @@ -28,21 +30,21 @@ import qualified Data.Text as T import qualified Data.Text.IO as T import Pipes import qualified Pipes.Safe.Prelude as Safe -import qualified Pipes.Safe as Safe -import Pipes.Safe (MonadSafe(..), Base(..)) +import Pipes.Safe (MonadSafe(..)) import Prelude hiding (readFile, writeFile) {- $textio - Where pipes IO replaces lazy IO, @Producer Text m r@ replaces lazy 'Text'. + Where pipes @IO@ replaces lazy @IO@, @Producer Text IO r@ replaces lazy 'Text'. This module exports some convenient functions for producing and consuming - pipes 'Text' in IO, with caveats described below. The main points are as in - + pipes 'Text' in @IO@, namely, 'readFile', 'writeFile', 'fromHandle', 'toHandle', + 'stdin' and 'stdout'. Some caveats described below. + + The main points are as in + : + + A 'Handle' can be associated with a 'Producer' or 'Consumer' according + as it is read or written to. - An 'IO.Handle' can be associated with a 'Producer' or 'Consumer' according as it is read or written to. - - To stream to or from 'IO.Handle's, one can use 'fromHandle' or 'toHandle'. For - example, the following program copies a document from one file to another: - > import Pipes > import qualified Pipes.Text as Text > import qualified Pipes.Text.IO as Text @@ -62,11 +64,12 @@ To stream from files, the following is perhaps more Prelude-like (note that it u > > main = runSafeT $ runEffect $ Text.readFile "inFile.txt" >-> Text.writeFile "outFile.txt" - You can stream to and from 'stdin' and 'stdout' using the predefined 'stdin' + Finally, you can stream to and from 'stdin' and 'stdout' using the predefined 'stdin' and 'stdout' pipes, as with the following \"echo\" program: > main = runEffect $ Text.stdin >-> Text.stdout + -} @@ -78,11 +81,11 @@ To stream from files, the following is perhaps more Prelude-like (note that it u * Like the functions in @Data.Text.IO@, they attempt to work with the system encoding. - * Like the functions in @Data.Text.IO@, they are slower than ByteString operations. Where + * Like the functions in @Data.Text.IO@, they significantly slower than ByteString operations. Where you know what encoding you are working with, use @Pipes.ByteString@ and @Pipes.Text.Encoding@ instead, e.g. @view utf8 Bytes.stdin@ instead of @Text.stdin@ - * Like the functions in @Data.Text.IO@ , they use Text exceptions. + * Like the functions in @Data.Text.IO@ , they use Text exceptions, not the standard Pipes protocols. Something like @@ -118,6 +121,19 @@ fromHandle h = go where go {-# INLINABLE fromHandle#-} + +fromHandleLn :: MonadIO m => IO.Handle -> Producer Text m () +fromHandleLn h = go where + getLine :: IO (Either G.IOException Text) + getLine = try (T.hGetLine h) + + go = do txt <- liftIO getLine + case txt of + Left e -> return () + Right y -> do yield y + go +{-# INLINABLE fromHandleLn #-} + -- | Stream text from 'stdin' stdin :: MonadIO m => Producer Text m () stdin = fromHandle IO.stdin @@ -135,6 +151,13 @@ readFile file = Safe.withFile file IO.ReadMode fromHandle {-# INLINE readFile #-} +{-| Stream lines of text from a file +-} +readFileLn :: MonadSafe m => FilePath -> Producer Text m () +readFileLn file = Safe.withFile file IO.ReadMode fromHandleLn +{-# INLINE readFileLn #-} + + {-| Stream text to 'stdout' Unlike 'toHandle', 'stdout' gracefully terminates on a broken output pipe. @@ -167,9 +190,6 @@ toHandle :: MonadIO m => IO.Handle -> Consumer' Text m r toHandle h = for cat (liftIO . T.hPutStr h) {-# INLINABLE toHandle #-} -{-# RULES "p >-> toHandle h" forall p h . - p >-> toHandle h = for p (\txt -> liftIO (T.hPutStr h txt)) - #-} -- | Stream text into a file. Uses @pipes-safe@.