packages feed

conduit 1.0.9.3 → 1.0.10

raw patch · 4 files changed

+88/−3 lines, 4 files

Files

Data/Conduit/Binary.hs view
@@ -30,13 +30,14 @@     , drop     , sinkCacheLength     , sinkLbs+    , mapM_       -- ** Conduits     , isolate     , takeWhile     , Data.Conduit.Binary.lines     ) where -import Prelude hiding (head, take, drop, takeWhile, dropWhile)+import Prelude hiding (head, take, drop, takeWhile, dropWhile, mapM_) import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L import Data.Conduit@@ -45,6 +46,7 @@ import Control.Monad (unless) import Control.Monad.IO.Class (liftIO, MonadIO) import Control.Monad.Trans.Resource (allocate, release)+import Control.Monad.Trans.Class (lift) import qualified System.IO as IO import Data.Word (Word8, Word64) import Control.Applicative ((<$>))@@ -377,3 +379,20 @@ -- Since 1.0.5 sinkLbs :: Monad m => Sink S.ByteString m L.ByteString sinkLbs = fmap L.fromChunks consume++-- | Perform a computation on each @Word8@ in a stream.+--+-- Since 1.0.10+mapM_ :: Monad m => (Word8 -> m ()) -> Consumer S.ByteString m ()+mapM_ f =+    awaitForever (lift . go)+  where+    go bs =+        loop 0+      where+        len = S.length bs+        loop i+            | i < len = do+                f (S.index bs i)+                loop (i + 1)+            | otherwise = return ()
Data/Conduit/Util.hs view
@@ -3,12 +3,14 @@     ( -- * Misc       zip     , zipSinks+    , passthroughSink     ) where  import Prelude hiding (zip) import Control.Monad (liftM, liftM2)-import Data.Conduit.Internal (Pipe (..), Source, Sink, injectLeftovers, ConduitM (..))+import Data.Conduit.Internal (Pipe (..), Source, Sink, injectLeftovers, ConduitM (..), Conduit, awaitForever, yield, await) import Data.Void (Void, absurd)+import Control.Monad.Trans.Class (lift)  -- | Combines two sources. The new source will stop producing once either --   source has been exhausted.@@ -55,3 +57,40 @@     NeedInput px cx  >< NeedInput py cy  = NeedInput (\i -> px i >< py i) (\() -> cx () >< cy ())     NeedInput px cx  >< y@Done{}         = NeedInput (\i -> px i >< y)    (\u -> cx u >< y)     x@Done{}         >< NeedInput py cy  = NeedInput (\i -> x >< py i)    (\u -> x >< cy u)++-- | Turn a @Sink@ into a @Conduit@ in the following way:+--+-- * All input passed to the @Sink@ is yielded downstream.+--+-- * When the @Sink@ finishes processing, the result is passed to the provided to the finalizer function.+--+-- Note that the @Sink@ will stop receiving input as soon as the downstream it+-- is connected to shuts down.+--+-- An example usage would be to write the result of a @Sink@ to some mutable+-- variable while allowing other processing to continue.+--+-- Since 1.0.10+passthroughSink :: Monad m+                => Sink i m r+                -> (r -> m ()) -- ^ finalizer+                -> Conduit i m i+passthroughSink (ConduitM sink0) final =+    ConduitM $ go [] sink0+  where+    go _ (Done r) = do+        lift $ final r+        awaitForever yield+    go is (Leftover sink i) = go (i:is) sink+    go _ (HaveOutput _ _ o) = absurd o+    go is (PipeM mx) = do+        x <- lift mx+        go is x+    go (i:is) (NeedInput next _) = go is (next i)+    go [] (NeedInput next done) = do+        mx <- await+        case mx of+            Nothing -> go [] (done ())+            Just x -> do+                yield x+                go [] (next x)
conduit.cabal view
@@ -1,5 +1,5 @@ Name:                conduit-Version:             1.0.9.3+Version:             1.0.10 Synopsis:            Streaming data processing library. Description:     @conduit@ is a solution to the streaming data problem, allowing for production, transformation, and consumption of streams of data in constant memory. It is an alternative to lazy I\/O which guarantees deterministic resource handling, and fits in the same general solution space as @enumerator@\/@iteratee@ and @pipes@. For a tutorial, please visit <https://haskell.fpcomplete.com/user/snoyberg/library-documentation/conduit-overview>.
test/main.hs view
@@ -936,6 +936,33 @@                 lbs' `shouldBe` lbs                 fromIntegral len `shouldBe` L.length lbs' +    describe "Data.Conduit.Binary.mapM_" $ do+        prop "telling works" $ \bytes ->+            let lbs = L.pack bytes+                src = CB.sourceLbs lbs+                sink = CB.mapM_ (tell . return . S.singleton)+                bss = execWriter $ src C.$$ sink+             in L.fromChunks bss == lbs++    describe "passthroughSink" $ do+        it "works" $ do+            ref <- I.newIORef (-1)+            let sink = CL.fold (+) (0 :: Int)+                conduit = C.passthroughSink sink (I.writeIORef ref)+                input = [1..10]+            output <- mapM_ C.yield input C.$$ conduit C.=$ CL.consume+            output `shouldBe` input+            x <- I.readIORef ref+            x `shouldBe` sum input+        it "does nothing when downstream does nothing" $ do+            ref <- I.newIORef (-1)+            let sink = CL.fold (+) (0 :: Int)+                conduit = C.passthroughSink sink (I.writeIORef ref)+                input = [undefined]+            mapM_ C.yield input C.$$ conduit C.=$ return ()+            x <- I.readIORef ref+            x `shouldBe` (-1)+     describe "mtl instances" $ do         it "ErrorT" $ do             let src = flip catchError (const $ C.yield 4) $ do