module Functions.Paths ( joinPaths , fileComponents , hasExtension , listDirectory , isDirectory , makeDir , copyFile , copyTo ) where import Functions.Text (lowerString) import Functions.General (elemOf) import Types (IsFunctionIO(..), Token(..)) import DependencyGenerator (DepGenM, TokenableTo(..), onToken, onTupleToken, toTupleToken, runFunctionIO, runFunctionIO_, untupleSndDepGenM) import qualified System.Directory as SD joinPaths :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM (Token FilePath) joinPaths = onTupleToken $ \s0 s1 -> s0 ++ "/" ++ s1 fileComponents :: TokenableTo FilePath a => a -> DepGenM (Token (String, String)) fileComponents = onToken $ \s -> let (lastRev, firstRev) = span (/= '.') $ reverse s (base, ext) = case firstRev of _ : firstRev' -> (reverse firstRev', reverse lastRev) [] -> (reverse lastRev, "") in (base, ext) hasExtension :: (TokenableTo [String] a, TokenableTo FilePath b) => a -> b -> DepGenM (Token Bool) hasExtension exts filename = do ext <- lowerString =<< untupleSndDepGenM =<< fileComponents filename ext `elemOf` exts data ListDirectory = ListDirectory deriving Show instance IsFunctionIO ListDirectory FilePath [FilePath] where evalFunctionIO ListDirectory s = SD.listDirectory s functionIOTouchesFilesystem ListDirectory = False listDirectory :: TokenableTo FilePath a => a -> DepGenM (Token [FilePath]) listDirectory a = runFunctionIO ListDirectory =<< toToken a data IsDirectory = IsDirectory deriving Show instance IsFunctionIO IsDirectory FilePath Bool where evalFunctionIO IsDirectory s = SD.doesDirectoryExist s functionIOTouchesFilesystem IsDirectory = False isDirectory :: TokenableTo FilePath a => a -> DepGenM (Token Bool) isDirectory a = runFunctionIO IsDirectory =<< toToken a data MakeDir = MakeDir deriving Show instance IsFunctionIO MakeDir FilePath () where evalFunctionIO MakeDir s = SD.createDirectory s functionIOTouchesFilesystem MakeDir = True makeDir :: TokenableTo FilePath a => a -> DepGenM () makeDir a = runFunctionIO_ MakeDir =<< toToken a data CopyFile = CopyFile deriving Show instance IsFunctionIO CopyFile (FilePath, FilePath) () where evalFunctionIO CopyFile (source, target) = SD.copyFile source target functionIOTouchesFilesystem CopyFile = True copyFile :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM () copyFile a b = runFunctionIO_ CopyFile =<< toTupleToken a b copyTo :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM () copyTo path targetDir = do pathToken <- toToken path copyFile pathToken =<< joinPaths targetDir pathToken