module Data.Conduit.Filesystem
( traverse
, sourceFile
, sinkFile
) where
import Prelude hiding (FilePath)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import Filesystem
import Filesystem.Path.CurrentOS (FilePath, encodeString)
import qualified Data.ByteString as S
#ifdef CABAL_OS_WINDOWS
#else
import qualified System.Posix as Posix
#endif
traverse :: MonadIO m
=> Bool
-> FilePath
-> Producer m FilePath
traverse _followSymlinks root =
liftIO (listDirectory root) >>= pull
where
pull [] = return ()
pull (p:ps) = do
isFile' <- liftIO $ isFile p
if isFile'
then yield p >> pull ps
else do
follow' <- liftIO $ follow p
if follow'
then do
ps' <- liftIO $ listDirectory p
pull ps
pull ps'
else pull ps
follow :: FilePath -> IO Bool
#ifdef CABAL_OS_WINDOWS
follow = isDirectory
#else
follow p = do
let path = encodeString p
stat <- if _followSymlinks
then Posix.getFileStatus path
else Posix.getSymbolicLinkStatus path
return (Posix.isDirectory stat)
#endif
sourceFile :: MonadResource m
=> FilePath
-> Producer m S.ByteString
sourceFile = CB.sourceFile . encodeString
sinkFile :: MonadResource m
=> FilePath
-> Consumer S.ByteString m ()
sinkFile = CB.sinkFile . encodeString