@@ -5,11 +5,8 @@
5{-# LANGUAGE DeriveDataTypeable #-}
5{-# LANGUAGE DeriveDataTypeable #-}
6module Data.Conduit
6module Data.Conduit
7 ( -- * Helper types
7 ( -- * Helper types
9− , ConduitResult (..)
8+ ConduitResult (..)
10 -- * Main types
9 -- * Main types
14 -- * Connect pieces together
11 -- * Connect pieces together
@@ -17,153 +14,55 @@ module Data.Conduit
19 -- * Other modules
16 -- * Other modules
20 , module Data.Conduit.Types.Source
18 , module Data.Conduit.Types.Source
21 , module Data.Conduit.Util.Source
19 , module Data.Conduit.Util.Source
21+ , module Data.Conduit.Types.Sink
22+ , module Data.Conduit.Util.Sink
24import Control.Monad.Trans.Resource
25import Control.Monad.Trans.Resource
25import Control.Monad.Trans.Control (MonadBaseControl)
26import Control.Monad.Trans.Control (MonadBaseControl)
26−import Control.Monad.Trans.Class (MonadTrans (lift))
27−import Control.Monad.Base (MonadBase (liftBase))
28−import Control.Exception.Lifted (throwIO, Exception)
29−import qualified Data.IORef as I
30−import Data.Typeable (Typeable)
31−import Control.Monad (liftM)
32−import Control.Applicative (Applicative (..))
33import Data.Conduit.Types.Source
27import Data.Conduit.Types.Source
34import Data.Conduit.Util.Source
28import Data.Conduit.Util.Source
35−
29+import Data.Conduit.Types.Sink
36−data SinkResult input output = SinkResult [input] (Maybe output)
30+import Data.Conduit.Util.Sink
37−instance Functor (SinkResult input) where
38− fmap f (SinkResult input moutput) = SinkResult input (fmap f moutput)
40data ConduitResult input output = ConduitResult [input] (Stream output)
32data ConduitResult input output = ConduitResult [input] (Stream output)
42−type SinkInsideData a m b = Stream a -> ResourceT m (SinkResult a b)
43−data SinkInside a m b =
44− SinkData (SinkInsideData a m b)
46−newtype Sink input m output = Sink (ResourceT m (SinkInside input m output))
47−instance Monad m => Functor (Sink input m) where
48− fmap f (Sink msink) = Sink $ do
50− return $ case sinkI of
51− SinkData sink -> SinkData $ liftM (fmap f) . sink
52− SinkNoData x -> SinkNoData $ f x
53−instance MonadBaseControl IO m => Applicative (Sink input m) where
54− pure x = Sink $ return $ SinkNoData x
55− Sink mf <*> Sink ma = Sink $ do
59− (SinkNoData f', SinkNoData a') -> return $ SinkNoData (f' a')
61− let toEither (SinkData x) = Left x
62− toEither (SinkNoData x) = Right x
63− istate <- liftBase $ I.newIORef (toEither f, toEither a)
64− return $ appHelper istate
66−appHelper :: MonadBaseControl IO m
68− ( Either (SinkInsideData input m (a -> b)) (a -> b)
69− , Either (SinkInsideData input m a) a
71− -> SinkInside input m b
72−appHelper istate = SinkData $ \stream0 -> do
73− state <- liftBase $ I.readIORef istate
76− go (Left f, eb) stream = do
77− SinkResult leftover mres <- f stream
79− Nothing -> return $ SinkResult leftover Nothing
81− let state' = (Right res, eb)
82− liftBase $ I.writeIORef istate state'
83− go state' $ Chunks leftover
84− go (f@Right{}, Left b) stream = do
85− SinkResult leftover mres <- b stream
87− Nothing -> return $ SinkResult leftover Nothing
89− let state' = (f, Right res)
90− liftBase $ I.writeIORef istate state'
91− go state' $ Chunks leftover
92− go (Right f, Right b) EOF = return $ SinkResult [] (Just $ f b)
93− go (Right f, Right b) (Chunks s) = return $ SinkResult s (Just $ f b)
95−instance MonadBaseControl IO m => Monad (Sink input m) where
97− x >>= f = sinkJoin (fmap f x)
99−instance MonadBaseControl IO m => MonadBase IO (Sink input m) where
100− liftBase = lift . liftBase
102−instance MonadTrans (Sink input) where
103− lift f = Sink (lift (liftM SinkNoData f))
105−sinkJoin :: MonadBaseControl IO m => Sink a m (Sink a m b) -> Sink a m b
106−sinkJoin (Sink msinkI) = Sink $ do
109− SinkNoData (Sink inner) -> inner
110− SinkData msink -> do
111− istate <- liftBase $ I.newIORef Nothing
112− return $ SinkData $ go istate msink
114− go :: MonadBaseControl IO m
115− => I.IORef (Maybe (SinkInsideData a m b))
116− -> (Stream a -> ResourceT m (SinkResult a (Sink a m b)))
117− -> SinkInsideData a m b
118− go istate outer stream = do
119− state <- liftBase $ I.readIORef istate
122− SinkResult leftover minner' <- outer stream
124− Just (Sink msink) -> do
127− SinkData inner -> do
128− liftBase $ I.writeIORef istate $ Just inner
130− then return $ SinkResult [] Nothing
131− else go istate outer $ Chunks leftover
132− SinkNoData x -> return $ SinkResult leftover $ Just x
133− Nothing -> return $ SinkResult leftover Nothing
134− Just inner -> inner stream
136type Conduit a m b = Stream a -> ResourceT m (ConduitResult a b)
34type Conduit a m b = Stream a -> ResourceT m (ConduitResult a b)
138infixr 0 $$
36infixr 0 $$
140−($$) :: MonadBaseControl IO m => Source m a -> Sink a m b -> ResourceT m b
38+($$) :: MonadBaseControl IO m => Source m a -> SinkM a m b -> ResourceT m b
141−source $$ Sink msink = do
39+source $$ SinkM msink = do
142 sinkI <- msink
40 sinkI <- msink
143 case sinkI of
41 case sinkI of
144 SinkNoData output -> return output
42 SinkNoData output -> return output
145− SinkData sink -> do
43+ SinkData push close -> do
146 bs <- bsource source
44 bs <- bsource source
147− connect' bs sink
45+ connect' bs push close
149− connect' bs sink = do
47+ connect' bs push close = do
150 stream <- bsourcePull bs
48 stream <- bsourcePull bs
151− SinkResult leftover mres <- sink stream
51+ SinkResult leftover res <- close
52+ bsourceUnpull bs leftover
55+ SinkResult leftover mres <- push a
152− bsourceUnpull bs leftover
56+ bsourceUnpull bs leftover
153− case (stream, mres) of
57+ case mres of
154− (_, Just res) -> return res
58+ Just res -> return res
155− (Chunks _, Nothing) -> connect' bs sink
59+ Nothing -> connect' bs push close
156− (EOF, Nothing) -> liftBase (throwIO NothingAfterEOF)
158infixr 0 <$$>
61infixr 0 <$$>
160−(<$$>) :: MonadBaseControl IO m => SourceM m a -> Sink a m b -> ResourceT m b
63+(<$$>) :: MonadBaseControl IO m => SourceM m a -> SinkM a m b -> ResourceT m b
161SourceM msrc <$$> sink = msrc >>= ($$ sink)
64SourceM msrc <$$> sink = msrc >>= ($$ sink)
163−data NothingAfterEOF = NothingAfterEOF
164− deriving (Show, Typeable)
165−instance Exception NothingAfterEOF
167infixl 1 $=
66infixl 1 $=
169($=) :: MonadBaseControl IO m
68($=) :: MonadBaseControl IO m
@@ -182,12 +81,13 @@ _ $= _ =
183infixr 0 =$
82infixr 0 =$
185−(=$) :: MonadBaseControl IO m => Conduit a m b -> Sink b m c -> Sink a m c
84+(=$) :: MonadBaseControl IO m => Conduit a m b -> SinkM b m c -> SinkM a m c
186−pipe =$ Sink msink = Sink $ do
85+_ =$ _ = SinkM $ do
187− sinkI <- msink
86+ undefined {-
188 case sinkI of
87 case sinkI of
189 SinkData sink -> return $ SinkData $ \stream -> do
88 SinkData sink -> return $ SinkData $ \stream -> do
190 ConduitResult leftover stream' <- pipe stream
89 ConduitResult leftover stream' <- pipe stream
191 SinkResult _thisislost mres <- sink stream'
90 SinkResult _thisislost mres <- sink stream'
192 return $ SinkResult leftover mres
91 return $ SinkResult leftover mres
193 SinkNoData mres -> return $ SinkNoData mres
92 SinkNoData mres -> return $ SinkNoData mres