module UnliftIO.Streams
  ( -- * Stream types
    InputStream
  , OutputStream

    -- * Creating streams
  , makeInputStream
  , makeOutputStream

    -- * Primitive stream operations
  , read
  , unRead
  , peek
  , write
  , writeTo
  , atEOF

    -- * Utility streams

  , nullInput
  , nullOutput

    -- * Batteries included
  , module UnliftIO.Streams.ByteString
  , module UnliftIO.Streams.Combinators
  , module UnliftIO.Streams.File
  , module UnliftIO.Streams.List
  , module UnliftIO.Streams.Text
  ) where

import           Control.Monad.IO.Unlift (MonadUnliftIO, liftIO, withRunInIO)
import           Prelude hiding (read)
import           System.IO.Streams (InputStream, OutputStream)
import qualified System.IO.Streams as S
import           UnliftIO.Streams.Combinators
import           UnliftIO.Streams.ByteString
import           UnliftIO.Streams.File
import           UnliftIO.Streams.List
import           UnliftIO.Streams.Text

{-# INLINE makeInputStream #-}
makeInputStream :: MonadUnliftIO m => m (Maybe a) -> m (InputStream a)
makeInputStream :: forall (m :: * -> *) a.
MonadUnliftIO m =>
m (Maybe a) -> m (InputStream a)
makeInputStream m (Maybe a)
f = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io -> forall a. IO (Maybe a) -> IO (InputStream a)
S.makeInputStream (forall a. m a -> IO a
io forall a b. (a -> b) -> a -> b
$ m (Maybe a)
f)

{-# INLINE makeOutputStream #-}
makeOutputStream :: MonadUnliftIO m => (Maybe a -> m ()) -> m (OutputStream a)
makeOutputStream :: forall (m :: * -> *) a.
MonadUnliftIO m =>
(Maybe a -> m ()) -> m (OutputStream a)
makeOutputStream Maybe a -> m ()
f = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
io -> forall a. (Maybe a -> IO ()) -> IO (OutputStream a)
S.makeOutputStream (forall a. m a -> IO a
io forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> m ()
f)

{-# INLINE peek #-}
peek :: MonadUnliftIO m => InputStream a -> m (Maybe a)
peek :: forall (m :: * -> *) a.
MonadUnliftIO m =>
InputStream a -> m (Maybe a)
peek InputStream a
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. InputStream a -> IO (Maybe a)
S.peek InputStream a
as

{-# INLINE read #-}
read :: MonadUnliftIO m => InputStream a -> m (Maybe a)
read :: forall (m :: * -> *) a.
MonadUnliftIO m =>
InputStream a -> m (Maybe a)
read InputStream a
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. InputStream a -> IO (Maybe a)
S.read InputStream a
as

{-# INLINE unRead #-}
unRead :: MonadUnliftIO m => a -> InputStream a -> m ()
unRead :: forall (m :: * -> *) a.
MonadUnliftIO m =>
a -> InputStream a -> m ()
unRead a
a InputStream a
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> InputStream a -> IO ()
S.unRead a
a InputStream a
as

{-# INLINE write #-}
write :: MonadUnliftIO m => Maybe a -> OutputStream a -> m ()
write :: forall (m :: * -> *) a.
MonadUnliftIO m =>
Maybe a -> OutputStream a -> m ()
write Maybe a
a OutputStream a
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Maybe a -> OutputStream a -> IO ()
S.write Maybe a
a OutputStream a
as

{-# INLINE writeTo #-}
writeTo :: MonadUnliftIO m => OutputStream a -> Maybe a -> m ()
writeTo :: forall (m :: * -> *) a.
MonadUnliftIO m =>
OutputStream a -> Maybe a -> m ()
writeTo OutputStream a
as Maybe a
a = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. OutputStream a -> Maybe a -> IO ()
S.writeTo OutputStream a
as Maybe a
a

{-# INLINE atEOF #-}
atEOF :: MonadUnliftIO m => InputStream a -> m Bool
atEOF :: forall (m :: * -> *) a. MonadUnliftIO m => InputStream a -> m Bool
atEOF InputStream a
as = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. InputStream a -> IO Bool
S.atEOF InputStream a
as

{-# INLINE nullInput #-}
nullInput :: MonadUnliftIO m => m (InputStream a)
nullInput :: forall (m :: * -> *) a. MonadUnliftIO m => m (InputStream a)
nullInput = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IO (InputStream a)
S.nullInput

{-# INLINE nullOutput #-}
nullOutput :: MonadUnliftIO m => m (OutputStream a)
nullOutput :: forall (m :: * -> *) a. MonadUnliftIO m => m (OutputStream a)
nullOutput = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IO (OutputStream a)
S.nullOutput