module Potoki.Produce
(
Produce,
transform,
list,
vector,
hashMapRows,
fileBytes,
fileBytesAtOffset,
fileText,
stdinBytes,
directoryContents,
finiteMVar,
infiniteMVar,
)
where
import Potoki.Prelude
import Potoki.Core.Produce
import qualified Potoki.Fetch as A
import qualified Potoki.Core.Fetch as A
import qualified Potoki.Core.Consume as E
import qualified Potoki.Core.Transform as F
import qualified Data.Attoparsec.Types as I
import qualified Data.Attoparsec.ByteString as K
import qualified Data.Attoparsec.Text as L
import qualified Data.HashMap.Strict as B
import qualified Data.ByteString as D
import qualified Data.Vector as C
import qualified System.Directory as G
vector :: Vector input -> Produce input
vector vector =
Produce $ do
indexRef <- newIORef 0
let
fetch =
A.Fetch $ \ nil just -> do
index <- readIORef indexRef
writeIORef indexRef $! succ index
return $ case (C.!?) vector index of
Just !input -> just input
Nothing -> nil
in return (fetch, return ())
hashMapRows :: HashMap a b -> Produce (a, b)
hashMapRows =
list . B.toList
fileBytes :: FilePath -> Produce (Either IOException ByteString)
fileBytes path =
accessingHandle (openBinaryFile path ReadMode) A.handleBytes
fileBytesAtOffset :: FilePath -> Int -> Produce (Either IOException ByteString)
fileBytesAtOffset path offset =
accessingHandle acquire A.handleBytes
where
acquire =
do
handle <- openBinaryFile path ReadMode
hSeek handle AbsoluteSeek (fromIntegral offset)
return handle
accessingHandle :: IO Handle -> (Handle -> A.Fetch (Either IOException a)) -> Produce (Either IOException a)
accessingHandle acquireHandle fetch =
Produce (catchIOError normal failing)
where
normal =
do
handle <- acquireHandle
return (fetch handle, catchIOError (hClose handle) (const (return ())))
failing exception =
return (pure (Left exception), return ())
stdinBytes :: Produce (Either IOException ByteString)
stdinBytes =
Produce (return (A.handleBytes stdin, return ()))
directoryContents :: FilePath -> Produce (Either IOException FilePath)
directoryContents path =
Produce (catchIOError success failure)
where
success =
do
subPaths <- G.listDirectory path
ref <- newIORef (map (Right . mappend path . (:) '/') (sort subPaths))
return (A.list ref, return ())
failure exception =
return (pure (Left exception), return ())
fileText :: FilePath -> Produce (Either IOException Text)
fileText path =
Produce (catchIOError success failure)
where
success =
do
handle <- openFile path ReadMode
return (A.handleText handle, catchIOError (hClose handle) (const (return ())))
failure exception =
return (pure (Left exception), return ())
finiteMVar :: MVar (Maybe element) -> Produce element
finiteMVar var =
Produce (return (A.finiteMVar var, return ()))
infiniteMVar :: MVar element -> Produce element
infiniteMVar var =
Produce (return (A.infiniteMVar var, return ()))