-- | Various utility functions versions of @conduit@. module Data.Conduit.Util ( -- * Misc zip , zipSources , zipSinks , passthroughSink ) where import Prelude hiding (zip) import Data.Conduit.Internal (Pipe (..), Source, Sink, ConduitM (..), Conduit, awaitForever, yield, await, zipSinks, zipSources) import Data.Void (absurd) import Control.Monad.Trans.Class (lift) -- | Deprecated synonym for 'zipSources'. -- -- Since 0.3.0 zip :: Monad m => Source m a -> Source m b -> Source m (a, b) zip = zipSources {-# DEPRECATED zip "Use zipSources instead" #-} -- | 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)