conduit 1.3.0.2 → 1.3.0.3
raw patch · 6 files changed
+146/−55 lines, 6 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Conduit: ReleaseEarly :: ReleaseType
+ Conduit: ReleaseException :: ReleaseType
+ Conduit: ReleaseNormal :: ReleaseType
+ Conduit: allocateAcquire :: MonadResource m => Acquire a -> m (ReleaseKey, a)
+ Conduit: data Acquire a
+ Conduit: data ReleaseType
+ Conduit: mkAcquire :: () => IO a -> a -> IO () -> Acquire a
+ Conduit: mkAcquireType :: () => IO a -> a -> ReleaseType -> IO () -> Acquire a
+ Conduit: withAcquire :: MonadUnliftIO m => Acquire a -> a -> m b -> m b
+ Data.Conduit.Internal: runConduitPure :: ConduitT () Void Identity r -> r
+ Data.Conduit.Internal: runConduitRes :: MonadUnliftIO m => ConduitT () Void (ResourceT m) r -> m r
- Conduit: class MonadTrans (t :: (* -> *) -> * -> *)
+ Conduit: class MonadTrans (t :: * -> * -> * -> *)
- Conduit: data ResourceT (m :: * -> *) a :: (* -> *) -> * -> *
+ Conduit: data ResourceT (m :: * -> *) a
- Conduit: newtype Identity a :: * -> *
+ Conduit: newtype Identity a
- Conduit: primitive :: PrimMonad m => (State# PrimState m -> (# TupleRep [] RuntimeRep, LiftedRep, State# PrimState m, a #)) -> m a
+ Conduit: primitive :: PrimMonad m => State# PrimState m -> (# State# PrimState m, a #) -> m a
- Conduit: withRunInIO :: MonadUnliftIO m => ((forall a. () => m a -> IO a) -> IO b) -> m b
+ Conduit: withRunInIO :: MonadUnliftIO m => forall a. () => m a -> IO a -> IO b -> m b
- Data.Conduit: data Void :: *
+ Data.Conduit: data Void
- Data.Conduit.Internal: ConduitT :: (forall b. (r -> Pipe i i o () m b) -> Pipe i i o () m b) -> ConduitT i o m r
+ Data.Conduit.Internal: ConduitT :: forall b. (r -> Pipe i i o () m b) -> Pipe i i o () m b -> ConduitT i o m r
- Data.Conduit.Internal: await :: Monad m => Consumer i m (Maybe i)
+ Data.Conduit.Internal: await :: Pipe l i o u m (Maybe i)
- Data.Conduit.Internal: awaitForever :: Monad m => (i -> ConduitT i o m r) -> ConduitT i o m ()
+ Data.Conduit.Internal: awaitForever :: Monad m => (i -> Pipe l i o r m r') -> Pipe l i o r m r
- Data.Conduit.Internal: bracketP :: MonadResource m => IO a -> (a -> IO ()) -> (a -> ConduitT i o m r) -> ConduitT i o m r
+ Data.Conduit.Internal: bracketP :: MonadResource m => IO a -> (a -> IO ()) -> (a -> Pipe l i o u m r) -> Pipe l i o u m r
- Data.Conduit.Internal: infixl 1 $=
+ Data.Conduit.Internal: infixl 1 $=+
- Data.Conduit.Internal: infixr 0 $$
+ Data.Conduit.Internal: infixr 0 =$$+-
- Data.Conduit.Internal: infixr 2 .|
+ Data.Conduit.Internal: infixr 2 =$=
- Data.Conduit.Internal: leftover :: i -> ConduitT i o m ()
+ Data.Conduit.Internal: leftover :: l -> Pipe l i o u m ()
- Data.Conduit.Internal: mapInput :: Monad m => (i1 -> i2) -> (i2 -> Maybe i1) -> ConduitT i2 o m r -> ConduitT i1 o m r
+ Data.Conduit.Internal: mapInput :: Monad m => (i1 -> i2) -> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
- Data.Conduit.Internal: mapOutput :: Monad m => (o1 -> o2) -> ConduitT i o1 m r -> ConduitT i o2 m r
+ Data.Conduit.Internal: mapOutput :: Monad m => (o1 -> o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
- Data.Conduit.Internal: mapOutputMaybe :: Monad m => (o1 -> Maybe o2) -> ConduitT i o1 m r -> ConduitT i o2 m r
+ Data.Conduit.Internal: mapOutputMaybe :: Monad m => (o1 -> Maybe o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
- Data.Conduit.Internal: transPipe :: Monad m => (forall a. m a -> n a) -> ConduitT i o m r -> ConduitT i o n r
+ Data.Conduit.Internal: transPipe :: Monad m => (forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
- Data.Conduit.Internal: yield :: Monad m => o -> ConduitT i o m ()
+ Data.Conduit.Internal: yield :: Monad m => o -> Pipe l i o u m ()
- Data.Conduit.Internal: yieldM :: Monad m => m o -> ConduitT i o m ()
+ Data.Conduit.Internal: yieldM :: Monad m => m o -> Pipe l i o u m ()
Files
- ChangeLog.md +4/−0
- conduit.cabal +4/−2
- src/Data/Conduit.hs +0/−20
- src/Data/Conduit/Internal/Conduit.hs +39/−0
- src/Data/Conduit/Internal/Fusion.hs +85/−19
- test/Spec.hs +14/−14
ChangeLog.md view
@@ -1,3 +1,7 @@+## 1.3.0.3++* Improve fusion framework rewrite rules+ ## 1.3.0.2 * Replace `ReadMode` with `WriteMode` in `withSinkFile`
conduit.cabal view
@@ -1,5 +1,5 @@ Name: conduit-Version: 1.3.0.2+Version: 1.3.0.3 Synopsis: Streaming data processing library. description: `conduit` is a solution to the streaming data problem, allowing for production,@@ -58,7 +58,6 @@ if os(windows) build-depends: Win32- , filepath other-modules: System.Win32File cpp-options: -DWINDOWS else@@ -96,6 +95,9 @@ , filepath , unliftio >= 0.2.4.0 ghc-options: -Wall++ if os(windows)+ cpp-options: -DWINDOWS --test-suite doctests -- hs-source-dirs: test
src/Data/Conduit.hs view
@@ -104,23 +104,3 @@ import Data.Functor.Identity (Identity, runIdentity) import Control.Monad.Trans.Resource (ResourceT, runResourceT) import Control.Monad.IO.Unlift (MonadUnliftIO)---- | Run a pure pipeline until processing completes, i.e. a pipeline--- with @Identity@ as the base monad. This is equivalient to--- @runIdentity . runConduit@.------ @since 1.2.8-runConduitPure :: ConduitT () Void Identity r -> r-runConduitPure = runIdentity . runConduit-{-# INLINE runConduitPure #-}---- | Run a pipeline which acquires resources with @ResourceT@, and--- then run the @ResourceT@ transformer. This is equivalent to--- @runResourceT . runConduit@.------ @since 1.2.8-runConduitRes :: MonadUnliftIO m- => ConduitT () Void (ResourceT m) r- -> m r-runConduitRes = runResourceT . runConduit-{-# INLINE runConduitRes #-}
src/Data/Conduit/Internal/Conduit.hs view
@@ -34,6 +34,8 @@ , yieldM , leftover , runConduit+ , runConduitPure+ , runConduitRes , fuse , connect -- ** Composition@@ -97,6 +99,7 @@ import Control.Monad.Trans.Class (MonadTrans (lift)) import Control.Monad.IO.Unlift (MonadIO (liftIO), MonadUnliftIO, withRunInIO) import Control.Monad.Primitive (PrimMonad, PrimState, primitive)+import Data.Functor.Identity (Identity, runIdentity) import Data.Void (Void, absurd) import Data.Monoid (Monoid (mappend, mempty)) import Data.Semigroup (Semigroup ((<>)))@@ -730,6 +733,22 @@ -- Equivalent to 'fuse' and '=$=', however the latter is deprecated and will -- be removed in a future version. --+-- Note that, while this operator looks like categorical composition+-- (from "Control.Category"), there are a few reasons it's different:+--+-- * The position of the type parameters to 'ConduitT' do not+-- match. We would need to change @ConduitT i o m r@ to @ConduitT r+-- m i o@, which would preclude a 'Monad' or 'MonadTrans' instance.+--+-- * The result value from upstream and downstream are allowed to+-- differ between upstream and downstream. In other words, we would+-- need the type signature here to look like @ConduitT a b m r ->+-- ConduitT b c m r -> ConduitT a c m r@.+--+-- * Due to leftovers, we do not have a left identity in Conduit. This+-- can be achieved with the underlying @Pipe@ datatype, but this is+-- not generally recommended. See <https://stackoverflow.com/a/15263700>.+-- -- @since 1.2.8 (.|) :: Monad m => ConduitM a b m () -- ^ upstream@@ -1231,3 +1250,23 @@ {-# RULES "conduit: leftover l >> p" forall l (p :: ConduitT i o m r). leftover l >> p = ConduitT (Leftover (unConduitT p) l) #-} -}++-- | Run a pure pipeline until processing completes, i.e. a pipeline+-- with @Identity@ as the base monad. This is equivalient to+-- @runIdentity . runConduit@.+--+-- @since 1.2.8+runConduitPure :: ConduitT () Void Identity r -> r+runConduitPure = runIdentity . runConduit+{-# INLINE runConduitPure #-}++-- | Run a pipeline which acquires resources with @ResourceT@, and+-- then run the @ResourceT@ transformer. This is equivalent to+-- @runResourceT . runConduit@.+--+-- @since 1.2.8+runConduitRes :: MonadUnliftIO m+ => ConduitT () Void (ResourceT m) r+ -> m r+runConduitRes = runResourceT . runConduit+{-# INLINE runConduitRes #-}
src/Data/Conduit/Internal/Fusion.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE Trustworthy #-}+{-# LANGUAGE ScopedTypeVariables #-} module Data.Conduit.Internal.Fusion ( -- ** Types Step (..)@@ -25,6 +26,7 @@ import Data.Conduit.Internal.Pipe (Pipe (..)) import Data.Functor.Identity (Identity (runIdentity)) import Data.Void (Void, absurd)+import Control.Monad.Trans.Resource (runResourceT) -- | This is the same as stream fusion\'s Step. Constructors are renamed to -- avoid confusion with conduit names.@@ -66,9 +68,15 @@ ConduitWithStream (a .| b) (y . x) {-# INLINE fuseStream #-} -{-# RULES "conduit: fuseStream" forall left right.+{-# RULES "conduit: fuseStream (.|)" forall left right. unstream left .| unstream right = unstream (fuseStream left right) #-}+{-# RULES "conduit: fuseStream (fuse)" forall left right.+ fuse (unstream left) (unstream right) = unstream (fuseStream left right)+ #-}+{-# RULES "conduit: fuseStream (=$=)" forall left right.+ unstream left =$= unstream right = unstream (fuseStream left right)+ #-} runStream :: Monad m => ConduitWithStream () Void m r@@ -91,8 +99,13 @@ {-# RULES "conduit: runStream" forall stream. runConduit (unstream stream) = runStream stream #-}+{-# RULES "conduit: runStream (pure)" forall stream.+ runConduitPure (unstream stream) = runIdentity (runStream stream)+ #-}+{-# RULES "conduit: runStream (ResourceT)" forall stream.+ runConduitRes (unstream stream) = runResourceT (runStream stream)+ #-} -{- connectStream :: Monad m => ConduitWithStream () i m () -> ConduitWithStream i Void m r@@ -111,10 +124,8 @@ Skip s' -> loop s' Emit _ o -> absurd o {-# INLINE connectStream #-}--} -{- Deprecated-{-# RULES "conduit: connectStream" forall left right.+{-# RULES "conduit: connectStream ($$)" forall left right. unstream left $$ unstream right = connectStream left right #-} @@ -138,28 +149,54 @@ Emit s' i -> loop [] (p i) s' in ms0 >>= loop [] (sink0 Done) {-# INLINE connectStream1 #-}--} -{- Deprecated-{-# RULES "conduit: connectStream1" forall left right.+{-# RULES "conduit: connectStream1 ($$)" forall left right. unstream left $$ right = connectStream1 left right #-}--} -{-+{-# RULES "conduit: connectStream1 (runConduit/.|)" forall left right.+ runConduit (unstream left .| right) = connectStream1 left right+ #-}+{-# RULES "conduit: connectStream1 (runConduit/=$=)" forall left right.+ runConduit (unstream left =$= right) = connectStream1 left right+ #-}+{-# RULES "conduit: connectStream1 (runConduit/fuse)" forall left right.+ runConduit (fuse (unstream left) right) = connectStream1 left right+ #-} -Not only will this rule not fire reliably, but due to finalizers, it can change-behavior unless implemented very carefully. Odds are that the careful-implementation won't be any faster, so leaving this commented out for now.+{-# RULES "conduit: connectStream1 (runConduitPure/.|)" forall left right.+ runConduitPure (unstream left .| right) = runIdentity (connectStream1 left right)+ #-}+{-# RULES "conduit: connectStream1 (runConduitPure/=$=)" forall left right.+ runConduitPure (unstream left =$= right) = runIdentity (connectStream1 left right)+ #-}+{-# RULES "conduit: connectStream1 (runConduitPure/fuse)" forall left right.+ runConduitPure (fuse (unstream left) right) = runIdentity (connectStream1 left right)+ #-} -connectStream2 :: Monad m- => ConduitT () i m ()+{-# RULES "conduit: connectStream1 (runConduitRes/.|)" forall left right.+ runConduitRes (unstream left .| right) = runResourceT (connectStream1 left right)+ #-}+{-# RULES "conduit: connectStream1 (runConduitRes/=$=)" forall left right.+ runConduitRes (unstream left =$= right) = runResourceT (connectStream1 left right)+ #-}+{-# RULES "conduit: connectStream1 (runConduitRes/fuse)" forall left right.+ runConduitRes (fuse (unstream left) right) = runResourceT (connectStream1 left right)+ #-}++connectStream2 :: forall i m r. Monad m+ => ConduitT () i m () -> ConduitWithStream i Void m r -> m r connectStream2 (ConduitT src0) (ConduitWithStream _ fstream) =- run $ fstream $ Stream step' $ return (return (), src0 Done)+ run $ fstream $ Stream step' $ return (src0 Done) where- step' (_, Done ()) = return $ Stop ()+ step' :: Pipe () () i () m () -> m (Step (Pipe () () i () m ()) i ())+ step' (Done ()) = return $ Stop ()+ step' (HaveOutput pipe o) = return $ Emit pipe o+ step' (NeedInput _ c) = return $ Skip $ c ()+ step' (PipeM mp) = Skip <$> mp+ step' (Leftover p ()) = return $ Skip p {-# INLINE step' #-} run (Stream step ms0) =@@ -173,10 +210,39 @@ Skip s' -> loop s' {-# INLINE connectStream2 #-} -{-# RULES "conduit: connectStream2" forall left right.+{-# RULES "conduit: connectStream2 ($$)" forall left right. left $$ unstream right = connectStream2 left right #-}--}++{-# RULES "conduit: connectStream2 (runConduit/.|)" forall left right.+ runConduit (left .| unstream right) = connectStream2 left right+ #-}+{-# RULES "conduit: connectStream2 (runConduit/fuse)" forall left right.+ runConduit (fuse left (unstream right)) = connectStream2 left right+ #-}+{-# RULES "conduit: connectStream2 (runConduit/=$=)" forall left right.+ runConduit (left =$= unstream right) = connectStream2 left right+ #-}++{-# RULES "conduit: connectStream2 (runConduitPure/.|)" forall left right.+ runConduitPure (left .| unstream right) = runIdentity (connectStream2 left right)+ #-}+{-# RULES "conduit: connectStream2 (runConduitPure/fuse)" forall left right.+ runConduitPure (fuse left (unstream right)) = runIdentity (connectStream2 left right)+ #-}+{-# RULES "conduit: connectStream2 (runConduitPure/=$=)" forall left right.+ runConduitPure (left =$= unstream right) = runIdentity (connectStream2 left right)+ #-}++{-# RULES "conduit: connectStream2 (runConduitRes/.|)" forall left right.+ runConduitRes (left .| unstream right) = runResourceT (connectStream2 left right)+ #-}+{-# RULES "conduit: connectStream2 (runConduitRes/fuse)" forall left right.+ runConduitRes (fuse left (unstream right)) = runResourceT (connectStream2 left right)+ #-}+{-# RULES "conduit: connectStream2 (runConduitRes/=$=)" forall left right.+ runConduitRes (left =$= unstream right) = runResourceT (connectStream2 left right)+ #-} streamConduit :: ConduitT i o m r -> (Stream m i () -> Stream m o r)
test/Spec.hs view
@@ -11,7 +11,7 @@ import Data.Conduit.Combinators (slidingWindow, chunksOfE, chunksOfExactlyE) import Data.List (intersperse, sort, find, mapAccumL) import Safe (tailSafe)-import System.FilePath (takeExtension)+import System.FilePath (takeExtension, (</>)) import Test.Hspec import Test.Hspec.QuickCheck import qualified Data.Text as T@@ -134,12 +134,12 @@ res <- runConduitRes $ sourceDirectory "test" .| filterC (not . hasExtension' ".swp") .| sinkList sort res `shouldBe`- [ "test/Data"- , "test/Spec.hs"- , "test/StreamSpec.hs"- , "test/doctests.hs"- , "test/main.hs"- , "test/subdir"+ [ "test" </> "Data"+ , "test" </> "Spec.hs"+ , "test" </> "StreamSpec.hs"+ , "test" </> "doctests.hs"+ , "test" </> "main.hs"+ , "test" </> "subdir" ] it "sourceDirectoryDeep" $ do res1 <- runConduitRes@@ -147,13 +147,13 @@ res2 <- runConduitRes $ sourceDirectoryDeep True "test" .| filterC (not . hasExtension' ".swp") .| sinkList sort res1 `shouldBe`- [ "test/Data/Conduit/Extra/ZipConduitSpec.hs"- , "test/Data/Conduit/StreamSpec.hs"- , "test/Spec.hs"- , "test/StreamSpec.hs"- , "test/doctests.hs"- , "test/main.hs"- , "test/subdir/dummyfile.txt"+ [ "test" </> "Data" </> "Conduit" </> "Extra" </> "ZipConduitSpec.hs"+ , "test" </> "Data" </> "Conduit" </> "StreamSpec.hs"+ , "test" </> "Spec.hs"+ , "test" </> "StreamSpec.hs"+ , "test" </> "doctests.hs"+ , "test" </> "main.hs"+ , "test" </> "subdir" </> "dummyfile.txt" ] sort res1 `shouldBe` sort res2 prop "drop" $ \(T.pack -> input) count ->