packages feed

conduit 0.5.1 → 0.5.2

raw patch · 4 files changed

+102/−2 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Conduit: unwrapResumable :: MonadIO m => ResumableSource m o -> m (Source m o, m ())
+ Data.Conduit.Internal: unwrapResumable :: MonadIO m => ResumableSource m o -> m (Source m o, m ())

Files

Data/Conduit.hs view
@@ -37,6 +37,7 @@     , ($$+)     , ($$++)     , ($$+-)+    , unwrapResumable        -- * Utility functions     , transPipe
Data/Conduit/Internal.hs view
@@ -48,10 +48,11 @@     , mapInput     , sourceList     , withUpstream+    , unwrapResumable     ) where  import Control.Applicative (Applicative (..))-import Control.Monad ((>=>), liftM, ap)+import Control.Monad ((>=>), liftM, ap, when) import Control.Monad.Trans.Class (MonadTrans (lift)) import Control.Monad.IO.Class (MonadIO (liftIO)) import Control.Monad.Base (MonadBase (liftBase))@@ -59,6 +60,7 @@ import Data.Monoid (Monoid (mappend, mempty)) import Control.Monad.Trans.Resource import qualified GHC.Exts+import qualified Data.IORef as I  -- | The underlying datatype for all the types in this package.  In has six -- type parameters:@@ -540,3 +542,26 @@         loop       where         loop = awaitE >>= either (\u -> return (u, r)) (\_ -> loop)++-- | Unwraps a @ResumableSource@ into a @Source@ and a finalizer.+--+-- A @ResumableSource@ represents a @Source@ which has already been run, and+-- therefore has a finalizer registered. As a result, if we want to turn it+-- into a regular @Source@, we need to ensure that the finalizer will be run+-- appropriately. By appropriately, I mean:+--+-- * If a new finalizer is registered, the old one should not be called.+-- * If the old one is called, it should not be called again.+--+-- This function returns both a @Source@ and a finalizer which ensures that the+-- above two conditions hold. Once you call that finalizer, the @Source@ is+-- invalidated and cannot be used.+--+-- Since 0.5.2+unwrapResumable :: MonadIO m => ResumableSource m o -> m (Source m o, m ())+unwrapResumable (ResumableSource src final) = do+    ref <- liftIO $ I.newIORef True+    let final' = do+            x <- liftIO $ I.readIORef ref+            when x final+    return (liftIO (I.writeIORef ref False) >> src, final')
conduit.cabal view
@@ -1,5 +1,5 @@ Name:                conduit-Version:             0.5.1+Version:             0.5.2 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 brief tutorial, please see the "Data.Conduit" module.
test/main.hs view
@@ -35,6 +35,7 @@  main :: IO () main = hspec $ do+{-     describe "data loss rules" $ do         it "consumes the source to quickly" $ do             x <- runResourceT $ CL.sourceList [1..10 :: Int] C.$$ do@@ -688,6 +689,79 @@         it' "works" $ do             res <- CL.iterate (+ 1) (1 :: Int) C.$$ CL.isolate 10 C.=$ CL.fold (+) 0             res @?= sum [1..10]+            -}++    describe "unwrapResumable" $ do+        it' "works" $ do+            ref <- I.newIORef (0 :: Int)+            let src0 = do+                    C.yieldOr () $ I.writeIORef ref 1+                    C.yieldOr () $ I.writeIORef ref 2+                    C.yieldOr () $ I.writeIORef ref 3+            (rsrc0, Just ()) <- src0 C.$$+ CL.head++            x0 <- I.readIORef ref+            x0 @?= 0++            (_, final) <- C.unwrapResumable rsrc0++            x1 <- I.readIORef ref+            x1 @?= 0++            final++            x2 <- I.readIORef ref+            x2 @?= 1++        it' "isn't called twice" $ do+            ref <- I.newIORef (0 :: Int)+            let src0 = do+                    C.yieldOr () $ I.writeIORef ref 1+                    C.yieldOr () $ I.writeIORef ref 2+            (rsrc0, Just ()) <- src0 C.$$+ CL.head++            x0 <- I.readIORef ref+            x0 @?= 0++            (src1, final) <- C.unwrapResumable rsrc0++            x1 <- I.readIORef ref+            x1 @?= 0++            Just () <- src1 C.$$ CL.head++            x2 <- I.readIORef ref+            x2 @?= 2++            final++            x3 <- I.readIORef ref+            x3 @?= 2++        it' "source isn't used" $ do+            ref <- I.newIORef (0 :: Int)+            let src0 = do+                    C.yieldOr () $ I.writeIORef ref 1+                    C.yieldOr () $ I.writeIORef ref 2+            (rsrc0, Just ()) <- src0 C.$$+ CL.head++            x0 <- I.readIORef ref+            x0 @?= 0++            (src1, final) <- C.unwrapResumable rsrc0++            x1 <- I.readIORef ref+            x1 @?= 0++            () <- src1 C.$$ return ()++            x2 <- I.readIORef ref+            x2 @?= 0++            final++            x3 <- I.readIORef ref+            x3 @?= 1  it' :: String -> IO () -> Spec it' = it