module System.FilePath.FilePather.Find ( Find(..) ) where import Control.Monad.Identity import Control.Monad.Trans.Identity import Control.Comonad import System.FilePath.FilePather.RecursePredicate import System.FilePath.FilePather.FilterPredicate import System.FilePath.FilePather.FileType import System.Directory -- | Finds all files using the given recurse predicate and filter predicate in the given file path. class Find f where find :: FilterPredicateT f -> RecursePredicateT f -> FilePath -> IO [FilePath] instance Find Identity where find f' r' p = let f = runFilterPredicateT f' r = runRecursePredicateT r' keep :: Bool -> [FilePath] -> [FilePath] keep u = if u then (p:) else id rkeep :: [FilePath] -> Bool -> IO [FilePath] rkeep d u = return (keep u d) trkeep :: FileType -> IO [FilePath] trkeep t = rkeep [] $ runIdentity (f p t) in do fe <- doesFileExist p if fe then trkeep File else do de <- doesDirectoryExist p if de then let (Identity k) = f p Directory (Identity l) = r p in if l then do t <- getDirectoryContents p u <- liftM concat $ forM (filter (`notElem` [".", ".."]) t) (find f' r') rkeep u k else rkeep [] k else trkeep Unknown instance Find IO where find f' r' p = let f = runFilterPredicateT f' r = runRecursePredicateT r' keep :: Bool -> [FilePath] -> [FilePath] keep u = if u then (p:) else id rkeep :: [FilePath] -> Bool -> IO [FilePath] rkeep d u = return (keep u d) trkeep :: FileType -> IO [FilePath] trkeep t = f p t >>= rkeep [] in do fe <- doesFileExist p if fe then trkeep File else do de <- doesDirectoryExist p if de then do k <- f p Directory l <- r p if l then do t <- getDirectoryContents p u <- liftM concat $ forM (filter (`notElem` [".", ".."]) t) (find f' r') rkeep u k else rkeep [] k else trkeep Unknown instance Comonad f => Find (IdentityT f) where find f r = find (filterPredicateT $ \p -> Identity . extract . runFilterPredicateT f p) (recursePredicateT $ Identity . extract . runRecursePredicateT r)