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 +1/−0
- Data/Conduit/Internal.hs +26/−1
- conduit.cabal +1/−1
- test/main.hs +74/−0
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