Conduit.hs 890 B

123456789101112131415161718192021222324252627282930313233343536
  1. {- |
  2. Conduit interfaces for uniform IO targets.
  3. -}
  4. module System.IO.Uniform.Conduit (
  5. runConduit,
  6. source,
  7. sink
  8. ) where
  9. import System.IO.Uniform
  10. import Control.Monad.Extra
  11. import qualified Data.Conduit as C
  12. import Control.Monad.IO.Class
  13. import Data.ByteString (ByteString)
  14. chunkSize :: Int
  15. chunkSize = 4000
  16. {- |
  17. Places a target at both ends of a conduit pipe.
  18. -}
  19. runConduit :: (MonadIO m, UniformIO u) => u -> C.ConduitM ByteString ByteString m a -> m a
  20. runConduit trg f = C.runConduit $ source trg `C.fuse` f `C.fuseUpstream` sink trg
  21. source :: (MonadIO m, UniformIO u) => u -> C.Source m ByteString
  22. source u = unlessM (liftIO $ isEOF u) $ do
  23. dt <- liftIO $ uRead u chunkSize
  24. C.yield dt
  25. source u
  26. sink :: (UniformIO u, MonadIO m) => u -> C.Sink ByteString m ()
  27. sink u = do
  28. dt <- C.await
  29. case dt of
  30. Just dt' -> liftIO $ uPut u dt'
  31. Nothing -> liftIO $ uClose u