module Network.Legion.Conduit (
chanToSource,
chanToSink,
merge,
) where
import Control.Concurrent (forkIO)
import Control.Concurrent.Chan (Chan, newChan, writeChan, readChan)
import Control.Monad (void, forever)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Conduit (Source, Sink, ($$), await, ($=), yield, await)
import qualified Data.Conduit.List as CL (map)
chanToSource :: (MonadIO io) => Chan a -> Source io a
chanToSource chan = forever $ yield =<< liftIO (readChan chan)
chanToSink :: (MonadIO io) => Chan a -> Sink a io ()
chanToSink chan = do
val <- await
case val of
Nothing -> return ()
Just v -> do
liftIO (writeChan chan v)
chanToSink chan
merge :: (MonadIO io) => Source IO a -> Source IO b -> Source io (Either a b)
merge left right = do
chan <- liftIO newChan
(liftIO . void . forkIO) (left $= CL.map Left $$ chanToSink chan)
(liftIO . void . forkIO) (right $= CL.map Right $$ chanToSink chan)
chanToSource chan