module System.FileSystem.Across
( buildFileSystem
, fileSystemList
, foldFileSystem
, foldFiles
, mapFileSystem
) where
import Control.Arrow ( (|||) , (***) )
import System.FilePath ( (</>) )
import System.FileSystem.Types
import System.FileSystem.Operators
import System.FileSystem.Instances
import System.FileSystem.Utils
buildFileSystem :: [Path] -> FileSystem
buildFileSystem = foldr (<:) emptyFileSystem
fileSystemList :: FileSystem -> [(Either DirName File,FilePath)]
fileSystemList = fileSystemList' []
fileSystemList' :: FilePath -> FileSystem -> [(Either DirName File,FilePath)]
fileSystemList' fp = concat
. fmap ( (\(dn,fs) -> (Left dn,fp) : fileSystemList' (fp </> dn) fs)
||| (\f -> (Right f,fp) : [] ) ) . dirCnt
foldFileSystem :: FilePath
-> Either (FilePath
-> t -> Either DirName File -> t)
(FilePath
-> Either DirName File -> t -> t)
-> t
-> FileSystem
-> t
foldFileSystem fp eop = (. dirCnt) . f
where
f = case eop of
Left op -> foldl . g $ op fp
Right op -> foldr . flip . g . flip $ op fp
g op = \r ->
(\(dn,fs) -> op (foldFileSystem (fp </> dn) eop r fs) (Left dn))
||| op r . Right
foldFiles :: Either (t -> File -> t) (File -> t -> t)
-> t -> FileSystem -> t
foldFiles = foldFileSystem [] . f
where
f = (\op -> (\_ t eit -> const t ||| op t $ eit) )
<|> (\op -> (\_ eit t -> const t ||| (flip op) t $ eit) )
mapFileSystem :: InApp DirName
-> InApp File
-> InApp FileSystem
mapFileSystem f g = modDirCnt . fmap $ f *** mapFileSystem f g <|> g