module Network.IRC.Conduit.Internal.Conduits where
import Control.Arrow ((&&&))
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.ByteString (ByteString, isSuffixOf, singleton)
import Data.Conduit (Conduit, await, yield)
import Data.Monoid ((<>))
import qualified Data.ByteString as B
chunked :: Monad m => Conduit ByteString m ByteString
chunked = chunked' ""
where
chunked' leftover = do
val <- await
case val of
Just val' ->
let
carriage = fromIntegral $ fromEnum '\r'
newline = fromIntegral $ fromEnum '\n'
bytes = B.filter (/=carriage) $ leftover <> val'
splitted = B.split newline bytes
(toyield, remainder)
| singleton newline `isSuffixOf` bytes = (splitted, "")
| otherwise = init &&& last $ splitted
in do
mapM_ yield $ filter (not . B.null) toyield
chunked' remainder
Nothing -> return ()
exceptionalConduit :: MonadIO m => Conduit a m a
exceptionalConduit = do
val <- await
case val of
Just x -> yield x >> exceptionalConduit
Nothing -> liftIO . ioError $ userError "Upstream source closed."