{-# 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