module ServantSerf.Directory where

import qualified ServantSerf.Type.Depth as Depth
import qualified System.Directory as Directory
import qualified System.FilePath as FilePath

list :: Depth.Depth -> FilePath -> IO [FilePath]
list :: Depth -> FilePath -> IO [FilePath]
list Depth
depth = case Depth
depth of
  Depth
Depth.Deep -> FilePath -> IO [FilePath]
listDeep
  Depth
Depth.Shallow -> FilePath -> IO [FilePath]
listShallow

listDeep :: FilePath -> IO [FilePath]
listDeep :: FilePath -> IO [FilePath]
listDeep FilePath
directory = do
  [FilePath]
entries <- FilePath -> IO [FilePath]
listShallow FilePath
directory
  forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM FilePath -> IO [FilePath]
listDeepHelper [FilePath]
entries

listDeepHelper :: FilePath -> IO [FilePath]
listDeepHelper :: FilePath -> IO [FilePath]
listDeepHelper FilePath
entry = do
  Bool
isDirectory <- FilePath -> IO Bool
Directory.doesDirectoryExist FilePath
entry
  if Bool
isDirectory then FilePath -> IO [FilePath]
listDeep FilePath
entry else forall (f :: * -> *) a. Applicative f => a -> f a
pure [FilePath
entry]

listShallow :: FilePath -> IO [FilePath]
listShallow :: FilePath -> IO [FilePath]
listShallow FilePath
directory = do
  [FilePath]
entries <- FilePath -> IO [FilePath]
Directory.listDirectory FilePath
directory
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> FilePath -> FilePath
FilePath.combine FilePath
directory) [FilePath]
entries