{-# LANGUAGE TypeOperators #-}
module Foundation.Conduit
    ( Conduit
    , ResourceT
    , ZipSink (..)
    , await
    , awaitForever
    , yield
    , yields
    , yieldOr
    , leftover
    , runConduit
    , runConduitPure
    , runConduitRes
    , fuse
    , (.|)
    , sourceFile
    , sourceHandle
    , sinkFile
    , sinkHandle
    , sinkList
    , bracketConduit
    ) where

import Foundation.Conduit.Internal
import Foundation.Collection
import Foundation.IO
import Foundation.IO.File
import Basement.Compat.Base
import Foundation.Monad.Base
import Foundation.Array
import Foundation
import System.IO (Handle)


infixr 2 .|
-- | Operator version of 'fuse'.
(.|) :: Monad m => Conduit a b m () -> Conduit b c m r -> Conduit a c m r
.| :: forall (m :: * -> *) a b c r.
Monad m =>
Conduit a b m () -> Conduit b c m r -> Conduit a c m r
(.|) = forall (m :: * -> *) a b c r.
Monad m =>
Conduit a b m () -> Conduit b c m r -> Conduit a c m r
fuse
{-# INLINE (.|) #-}

sourceFile :: MonadResource m => FilePath -> Conduit i (UArray Word8) m ()
sourceFile :: forall (m :: * -> *) i.
MonadResource m =>
FilePath -> Conduit i (UArray Word8) m ()
sourceFile FilePath
fp = forall (m :: * -> *) a b i o r.
MonadResource m =>
IO a -> (a -> IO b) -> (a -> Conduit i o m r) -> Conduit i o m r
bracketConduit
    (FilePath -> IOMode -> IO Handle
openFile FilePath
fp IOMode
ReadMode)
    Handle -> IO ()
closeFile
    forall (m :: * -> *) i.
MonadIO m =>
Handle -> Conduit i (UArray Word8) m ()
sourceHandle

sourceHandle :: MonadIO m
             => Handle
             -> Conduit i (UArray Word8) m ()
sourceHandle :: forall (m :: * -> *) i.
MonadIO m =>
Handle -> Conduit i (UArray Word8) m ()
sourceHandle Handle
h =
    Conduit i (UArray Word8) m ()
loop
  where
    defaultChunkSize :: Int
    defaultChunkSize :: Int
defaultChunkSize = (Int
32 :: Int) forall a. Multiplicative a => a -> a -> a
* Int
1000 forall a. Subtractive a => a -> a -> Difference a
- Int
16
    loop :: Conduit i (UArray Word8) m ()
loop = do
        UArray Word8
arr <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Int -> IO (UArray Word8)
hGet Handle
h Int
defaultChunkSize)
        if forall c. Collection c => c -> Bool
null UArray Word8
arr
            then forall (m :: * -> *) a. Monad m => a -> m a
return ()
            else forall (m :: * -> *) o i. Monad m => o -> Conduit i o m ()
yield UArray Word8
arr forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Conduit i (UArray Word8) m ()
loop

-- | Send values downstream.
yields :: (Monad m, Foldable os, Element os ~ o) => os -> Conduit i o m ()
-- FIXME: Should be using mapM_ once that is in Foldable, see #334
yields :: forall (m :: * -> *) os o i.
(Monad m, Foldable os, Element os ~ o) =>
os -> Conduit i o m ()
yields = forall collection a.
Foldable collection =>
(Element collection -> a -> a) -> a -> collection -> a
foldr (forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (m :: * -> *) o i. Monad m => o -> Conduit i o m ()
yield) (forall (m :: * -> *) a. Monad m => a -> m a
return ())


sinkFile :: MonadResource m => FilePath -> Conduit (UArray Word8) i m ()
sinkFile :: forall (m :: * -> *) i.
MonadResource m =>
FilePath -> Conduit (UArray Word8) i m ()
sinkFile FilePath
fp = forall (m :: * -> *) a b i o r.
MonadResource m =>
IO a -> (a -> IO b) -> (a -> Conduit i o m r) -> Conduit i o m r
bracketConduit
    (FilePath -> IOMode -> IO Handle
openFile FilePath
fp IOMode
WriteMode)
    Handle -> IO ()
closeFile
    forall (m :: * -> *) o.
MonadIO m =>
Handle -> Conduit (UArray Word8) o m ()
sinkHandle

sinkHandle :: MonadIO m
           => Handle
           -> Conduit (UArray Word8) o m ()
sinkHandle :: forall (m :: * -> *) o.
MonadIO m =>
Handle -> Conduit (UArray Word8) o m ()
sinkHandle Handle
h =
    Conduit (UArray Word8) o m ()
loop
  where
    loop :: Conduit (UArray Word8) o m ()
loop = forall i o (m :: * -> *). Conduit i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (forall (m :: * -> *) a. Monad m => a -> m a
return ())
        (\UArray Word8
arr -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> UArray Word8 -> IO ()
hPut Handle
h UArray Word8
arr) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Conduit (UArray Word8) o m ()
loop)

sinkList :: Monad m => Conduit i o m [i]
sinkList :: forall (m :: * -> *) i o. Monad m => Conduit i o m [i]
sinkList =
    forall {a} {c} {o} {m :: * -> *}. ([a] -> c) -> Conduit a o m c
loop forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  where
    loop :: ([a] -> c) -> Conduit a o m c
loop [a] -> c
front = forall i o (m :: * -> *). Conduit i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
front []))
        (\a
x -> ([a] -> c) -> Conduit a o m c
loop ([a] -> c
front forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a
xforall a. a -> [a] -> [a]
:)))