{- | Conduit interfaces for uniform IO targets. -} module System.IO.Uniform.Conduit ( runConduit, source, sink ) where import System.IO.Uniform import Control.Monad.Extra import qualified Data.Conduit as C import Control.Monad.IO.Class import Data.ByteString (ByteString) chunkSize :: Int chunkSize = 4000 {- | Places a target at both ends of a conduit pipe. -} runConduit :: (MonadIO m, UniformIO u) => u -> C.ConduitM ByteString ByteString m a -> m a runConduit trg f = C.runConduit $ source trg `C.fuse` f `C.fuseUpstream` sink trg source :: (MonadIO m, UniformIO u) => u -> C.Source m ByteString source u = unlessM (liftIO $ isEOF u) $ do dt <- liftIO $ uRead u chunkSize C.yield dt source u sink :: (UniformIO u, MonadIO m) => u -> C.Sink ByteString m () sink u = do dt <- C.await case dt of Just dt' -> liftIO $ uPut u dt' Nothing -> liftIO $ uClose u