-- * Producers
fromHandle
+ , fromHandleLn
, stdin
, readFile
+ , readFileLn
-- * Consumers
, toHandle
, stdout
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
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
{-# 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.