bdcs-0.1.0: src/BDCS/Utils/Conduit.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
-- |
-- Module: BDCS.Utils.Conduit
-- Copyright: (c) 2016-2017 Red Hat, Inc.
-- License: LGPL
--
-- Maintainer: https://github.com/weldr
-- Stability: alpha
-- Portability: portable
--
-- Conduit related utility functions
module BDCS.Utils.Conduit(awaitWith,
identityC,
sourceInputStream)
where
import Conduit(mapC)
import Control.Monad(unless)
import Control.Monad.IO.Class(liftIO)
import Control.Monad.Trans.Resource(MonadResource)
import Data.ByteString(ByteString)
import Data.Conduit(Conduit, Producer, await, yield)
import Data.Maybe(fromMaybe)
import GI.Gio(IsInputStream, inputStreamReadBytes, noCancellable)
import GI.GLib(bytesGetData, bytesGetSize)
-- | Wait for a single value and then call fn on it.
awaitWith :: Monad m => (i -> Conduit i m o) -> Conduit i m o
awaitWith fn = await >>= \case
Nothing -> return ()
Just v -> fn v
-- | A conduit that takes its input and returns that as its output.
identityC :: Monad m => Conduit a m a
identityC = mapC id
-- | Convert a 'GI.Gio.IsInputStream' to a conduit source
sourceInputStream :: (MonadResource m, IsInputStream i) => i -> Producer m ByteString
sourceInputStream input = do
let buf_size = 8096
bytes <- liftIO $ inputStreamReadBytes input buf_size noCancellable
bytesSize <- liftIO $ bytesGetSize bytes
unless (bytesSize == 0) $ do
bytesData <- liftIO $ bytesGetData bytes
yield $ fromMaybe "" bytesData
sourceInputStream input